Java, 102 95 89 88 78 bytes
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>a=new B<>();}
Esto termina con lo StackOverflowError
que sucede porque el sistema de resolución genérico no puede decidir una raíz contra la cual resolver los otros genéricos.
Créditos donde vencen .
¿Qué pasa aquí?
A<T>
está ahí para tener un padre de 1 letra. Es genérico Podría haberlo usado List
, pero las importaciones y la repetición de 4 letras son demasiado largas.
B<T>
declara un genérico básico.
B extends A
se requiere tener una jerarquía entre B
y A
.
extends A<A>
crea una auto referencia en A<T>
.
A<? super B>
desencadena la búsqueda de genéricos en A<T>
B<B<T>>
crea una autorreferencia en B<T>
.
A<...> a=new B<>()
fuerza el uso de los genéricos, en lugar de simplemente la definición de los mismos, forzando la resolución al compilar B
, y no después.
A<?super B
crea una no referencia propia, por lo que tenemos una referencia a un tipo y a otro en los genéricos de A
.
B<A>
crea una no referencia propia, por lo que tenemos una referencia a un tipo y a otro en los genéricos de B
.
Ahora, el tipo A
tiene tipo genérico A
y B
, pero ¿cuál se debe elegir? Olvídate de ti mismo, tratemos de resolverlo B
. Silbido.
De acuerdo, ¿ B
tiene tipo genérico A
y B
, pero cuál elegir? Olvídate de ti mismo, tratemos de resolverlo A
. Apestar.
Este tipo de recursividad en realidad no puede ser evitado porque hay casos legítimos como A<B<A<B<A<B<Object>>>>>>
: por ejemplo, un objeto JSON: List<Map<String,Map<String,List<Map<String,List<String>>>>>>
.
Resultado de compilación
$ javac NoCompile.java
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2587)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3260)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2592)
at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2579)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:554)
En mi sistema, el seguimiento de la pila se detiene después de mostrar 1024 líneas, que en realidad son las 4 mismas líneas repetidas 256 veces, lo que demuestra una recursión infinita. Te ahorraré todo ese rastro.
Ahorros
- 102 → 95 bytes: reemplazado
interface
+ implements
con class
+ extends
.
- 95 → 89 bytes: reemplazado
Long
con A
(dos veces).
- 89 → 88 bytes: operador de diamante usado (
new B<A>()
→ new B<>()
).
- 88 → 78 bytes: movió la declaración de la variable a un miembro de la clase, gracias a VoteToClose .