Есть много разных ответов, поэтому я подумал, что было бы полезно собрать их все (и добавить несколько):
Классы
- Классы AutoBoxing - компилятор допускает только определенные классы
- Класс - имеет свои собственные литералы (например, int.class). Я бы также добавил его общую типизацию без создания новых экземпляров.
- Строка - с перегруженным + -оператором и поддержкой литералов
- Enum - единственный класс, который можно использовать в операторе switch (скоро привилегия будет предоставлена и String). Он также выполняет другие задачи (автоматическое создание статических методов, обработка сериализации и т. Д.), Но теоретически это можно сделать с помощью кода - это просто много шаблонов, и некоторые ограничения не могут быть применены в подклассах (например, специальные правила создания подклассов), но то, что вы никогда бы не смогли сделать без привилегированного статуса перечисления, - это включить его в оператор switch.
- Object - корень всех объектов (и я бы добавил, что методы clone и finalize - это не то, что вы могли бы реализовать)
- Ссылки : WeakReference, SoftReference, PhantomReference
- Поток - язык не дает вам конкретной инструкции для запуска потока, скорее он волшебным образом применяет ее к методу start ().
- Throwable - корень всех классов, которые могут работать с throw, throws и catch, а также понимание компилятором Exception vs. RuntimeException и Error.
- NullPointerException и другие исключения, такие как ArrayIndexOutOfBounds, которые могут быть выброшены другими инструкциями байт-кода, кроме athrow.
Интерфейсы
- Iterable - единственный интерфейс, который можно использовать в расширенном цикле for
Почетные упоминания относятся к:
- java.lang.reflect. Массив - создание нового массива, определенного объектом Class, было бы невозможно.
- Аннотации Это особая языковая функция, которая во время выполнения ведет себя как интерфейс. Вы, конечно, не можете определить другой интерфейс аннотации, так же как вы не можете определить замену для Object. Однако вы могли бы реализовать все их функции и просто иметь другой способ их получения (и целую кучу шаблонов), а не отражение. Фактически, до появления аннотаций существовало множество реализаций на основе XML и тегов javadoc.
- ClassLoader - он, безусловно, имеет привилегированные отношения с JVM, поскольку нет языкового способа загрузки класса, хотя есть способ байт-кода, поэтому он похож на Array в этом смысле. Он также имеет особую привилегию быть вызванным JVM, хотя это деталь реализации.
- Сериализуемый - вы можете реализовать эту функциональность через отражение, но у него есть собственное привилегированное ключевое слово, и вы потратите много времени на знакомство с SecurityManager в некоторых сценариях.
Примечание: я исключил из списка то, что предоставляет JNI (например, ввод-вывод), потому что вы всегда можете реализовать свой собственный вызов JNI, если бы вы были так склонны. Однако собственные вызовы, которые взаимодействуют с JVM привилегированными способами, отличаются.
Массивы спорны - они наследуют Object, имеют понятную иерархию (Object [] - это супертип String []), но они являются особенностями языка, а не определенным классом сами по себе.