Java, 102 95 89 88 78 octets
class A<T>{}class B<T>extends A<A<?super B<B<T>>>>{A<?super B<A>>a=new B<>();}
Cela se termine par un StackOverflowErrorqui se produit car le système de résolution générique ne peut pas décider d'une racine contre laquelle résoudre les autres génériques.
Crédits dus .
Que se passe t-il ici?
A<T>est juste là pour avoir un parent d'une lettre. C'est générique. J'aurais pu l'utiliser List, mais l'importation et la répétition de 4 lettres sont trop longues.
B<T> déclare un générique de base.
B extends Aest nécessaire d'avoir une hiérarchie entre Bet A.
extends A<A>crée une auto référence sur A<T>.
A<? super B> déclenche la recherche de génériques sur A<T>
B<B<T>>crée une auto-référence sur B<T>.
A<...> a=new B<>()force l'utilisation des génériques, au lieu de simplement la définition de ceux-ci, forçant la résolution lors de la compilation B, et non après.
A<?super Bcrée une non-référence de soi, nous avons donc à la fois une référence à un type et à un autre dans les génériques de A.
B<A>crée une non-référence de soi, nous avons donc à la fois une référence à un type et à un autre dans les génériques de B.
Maintenant, le type Aa le type générique Aet B, mais lequel doit être choisi? Oubliez vous-même, essayons de résoudre B. Ping
D'accord, les Bgénériques sont-ils de type Aet B, mais lequel doit être choisi? Oubliez vous-même, essayons de résoudre A. Pong
Ce genre de récursion ne peut pas vraiment être évité car il y a des cas légitimes comme A<B<A<B<A<B<Object>>>>>>: par exemple un objet JSON: List<Map<String,Map<String,List<Map<String,List<String>>>>>>.
Résultat de la compilation
$ 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)
Sur mon système, la trace de la pile s’arrête après avoir affiché 1024 lignes, qui sont en fait les 4 mêmes lignes répétées 256 fois, ce qui prouve une récursion infinie. Je vous épargne toute cette trace.
Des économies
- 102 → 95 octets: remplacé
interface+ implementspar class+ extends.
- 95 → 89 octets: remplacé
Longpar A(deux fois).
- 89 → 88 octets: opérateur diamant utilisé (
new B<A>()→ new B<>()).
- 88 → 78 octets: déplacé la déclaration de variable vers un membre de la classe, grâce à VoteToClose .