Java语言中的荣耀类
标准Java API中的某些类与其他类稍有不同。 我正在谈论那些没有编译器和/或JVM的特殊支持就无法实现的类。
我刚刚提出的是:
-
Object
(显然),因为它,除其他外,没有一个超级类。 -
String
作为语言对+运算符有特别的支持。 -
Thread
因为它有这个神奇的start()方法,尽pipe没有“分叉”执行的字节码指令。
我想所有这些类都是以这种或那种方式在JLS中提到的。 如我错了请纠正我。
无论如何,还有其他这样的类别存在吗? Java语言中有没有完整的“荣耀类”列表?
有很多不同的答案,所以我认为这将是有益的收集他们(并添加一些):
类
- AutoBoxing类 – 编译器只允许特定的类
- 类 – 有自己的文字(例如int.class)。 我也将添加它的generics,而不创build新的实例。
- string – 重载+操作符和文字的支持
- 枚举 – 可以在switch语句中使用的唯一类(很快也会赋予string特权)。 它还做了其他的事情(自动创build静态方法,序列化处理等),但理论上可以用代码完成 – 它只是很多样板,而且一些约束不能在子类中强制执行(例如特殊的子类规则),但是如果没有枚举的特权状态,你永远无法完成的事情是将它包含在switch语句中。
- 对象 – 所有对象的根(我会添加它的克隆和finalize方法是不是你可以实现的)
- 参考文献 :WeakReference,SoftReference,PhantomReference
- 线程 – 语言不给你一个启动线程的特定指令,而是神奇地将它应用到start()方法。
- Throwable – 可以使用throw,throws和catch的所有类的根,以及编译器对Exception与RuntimeException和Error的理解。
- NullPointerException和其他exception,比如ArrayIndexOutOfBounds可以被其他字节码指令抛出而不是抛出。
接口
- Iterable – 唯一可用于增强for循环的接口
尊敬的提到去:
- java.lang.reflect中。 数组 – 创build一个由Class对象定义的新数组是不可能的。
- 注解它们是一种特殊的语言特性,在运行时就像一个接口一样。 你当然不能定义另一个Annotation接口,就像你不能定义Object的replace一样。 然而,你可以实现所有的function,只是有另一种方式来检索它们(和一大堆样板),而不是reflection。 实际上,在引入注释之前,有许多基于XML和javadoc标签的实现。
- ClassLoader – 它当然和JVM有着特殊的关系,因为没有语言方法来加载一个类,虽然有一个字节码的方式,所以就像Array那样。 它也有被JVM调用的特殊权限,尽pipe这是一个实现细节。
- 可序列化 – 您可以通过reflection来实现function,但是它有自己的特权关键字,在某些情况下,您会花费大量的时间与SecurityManager保持亲密关系。
注意:我没有列出提供JNI的东西(比如IO),因为如果你这么倾向的话,你总是可以实现你自己的JNI调用。 但是,以特权方式与JVM交互的本地调用是不同的。
数组是有争议的 – 它们inheritanceObject,有一个理解的层次结构(Object []是String []的超types),但它们是语言特征,而不是自定义的类。
Class
,当然。 它有自己的文字(它与String
,BTW分享的区别),是所有reflection魔法的起点。
sun.misc.unsafe是所有肮脏,精神的语言突破黑客的母亲。
- 枚举。 你不可以inheritance它,但编译器可以。
- java.util.concurrent下的很多东西都可以在没有JVM支持的情况下实现,但是效率会差很多。
所有的Number类都以Autoboxing的forms有一点魔力。
由于提到了重要的课程 ,我将提到一些接口:
Iterable
接口(自1.5开始) – 它允许一个对象参与到一个foreach循环中:
Iterable<Foo> iterable = ...; for (Foo foo : iterable) { }
Serializable
接口有一个非常特殊的含义,与标准接口不同。 你可以定义方法,即使它们没有在接口中定义(如readResolve()
)也会被考虑。 transient
关键字是影响Serializable
实现者行为的语言元素。
- 可抛出,RuntimeException,错误AssertionError
- 参考 WeakReference,SoftReference,PhantomReference
- 枚举
- 注解
Java数组,如int[].class
java.lang.ClassLoader
,尽pipe实际的肮脏的工作是由一些未提及的子类来完成的(见12.2.1加载过程 )。
不确定这一点。 但我想不出一种手动实现IO对象的方法。
System
类有一些魔法。
System.arraycopy
是一个到本地代码的钩子
public static native void arraycopy(Object array1, int start1, Object array2, int start2, int length);
但…
/** * Private version of the arraycopy method used by the jit * for reference arraycopies */ private static void arraycopy(Object[] A1, int offset1, Object[] A2, int offset2, int length) { ... }
那么因为assert的特殊处理已经被提及了。 这里有一些更多的exceptiontypes,由jvm有特殊的处理:
- 空指针exception
- ArithmeticException。
- StackOverflowException
- 各种OutOfMemoryErrors
- …
例外情况并不特殊,但是jvm在特殊情况下使用它们,所以如果不编写自己的jvm,就不能实现它们。 我相信周围还有更多特殊的例外。
这些类中的大多数并不是真正用编译器或JVM提供的“特殊”帮助来实现的。 对象确实注册了一些围绕内部JVM结构的原生地址,但是您也可以为自己的类进行注册。 (我承认这是受语义限制的,“调用在JVM中定义的本地”可以被认为是特殊的JVM支持。)
“新”和“抛”指示如何初始化这些内部结构的行为是什么/特别的。
注释和数字几乎全是怪异的。