Il y a beaucoup de réponses différentes, alors j'ai pensé qu'il serait utile de les rassembler toutes (et d'en ajouter quelques-unes) :
Classes
-
AutoBoxing classes - le compilateur ne permet que des classes spécifiques
-
Classe - a ses propres littéraux (int.class par exemple). J'ajouterais également son typage générique sans créer de nouvelles instances.
-
Chaîne de caractères - avec son opérateur + surchargé et le support des littéraux.
-
Enum - la seule classe qui peut être utilisée dans une instruction switch (bientôt un privilège à accorder à String également). Elle fait également d'autres choses (création automatique de méthodes statiques, gestion de la sérialisation, etc.), mais celles-ci pourraient théoriquement être accomplies avec du code - il s'agit simplement d'un grand nombre d'expressions passe-partout, et certaines des contraintes ne pourraient pas être appliquées dans les sous-classes (par exemple, les règles spéciales de sous-classement), mais ce que vous ne pourriez jamais accomplir sans le statut privilégié d'une énumération est de l'inclure dans une instruction switch.
-
Objet - la Racine de tous les objets (et j'ajouterais que ses méthodes clone et finalize ne sont pas quelque chose que vous pourriez implémenter)
-
Références : WeakReference, SoftReference, PhantomReference
-
Fil conducteur - le langage ne vous donne pas d'instruction spécifique pour démarrer un fil, il l'applique par magie à la méthode start().
-
Jetable - la racine de toutes les classes qui peuvent fonctionner avec throw, throws et catch, ainsi que la compréhension par le compilateur des exceptions par rapport aux RuntimeException et aux erreurs.
-
NullPointerException et d'autres exceptions telles que ArrayIndexOutOfBounds qui peuvent être levées par d'autres instructions de bytecode que athrow.
Interfaces
-
Iterable - la seule interface qui peut être utilisée dans une boucle for améliorée
Les mentions honorables vont à :
- java.lang.reflect. Array - la création d'un nouveau tableau tel que défini par un objet Classe ne serait pas possible.
-
Annotations Il s'agit d'une fonctionnalité spéciale du langage qui se comporte comme une interface au moment de l'exécution. Vous ne pouvez certainement pas définir une autre interface Annotation, tout comme vous ne pouvez pas définir un remplacement pour Object. Cependant, vous pourriez implémenter toutes leurs fonctionnalités et disposer d'un autre moyen de les récupérer (et de tout un tas d'éléments passe-partout) plutôt que de recourir à la réflexion. En fait, il existait de nombreuses implémentations basées sur XML et sur les balises javadoc avant l'introduction des annotations.
-
ClassLoader - elle a certainement une relation privilégiée avec la JVM car il n'y a pas de moyen linguistique de charger une classe, bien qu'il y ait un moyen en bytecode, donc elle est comme Array de cette façon. Il a également le privilège spécial d'être rappelé par la JVM, bien que ce soit un détail d'implémentation.
-
Serializable - vous pourriez implémenter la fonctionnalité via la réflexion, mais elle a son propre mot-clé privilégié et vous passeriez beaucoup de temps à vous familiariser avec le SecurityManager dans certains scénarios.
Remarque : J'ai exclu de la liste les éléments qui fournissent JNI (comme IO) parce que vous pouvez toujours implémenter votre propre appel JNI si vous le souhaitez. Cependant, les appels natifs qui interagissent avec la JVM de manière privilégiée sont différents.
Les tableaux sont discutables - ils héritent d'Object, ont une hiérarchie comprise (Object[] est un supertype de String[]), mais ils sont une caractéristique du langage, pas une classe définie en soi.