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是所有肮脏,精神的语言突破黑客的母亲。

  1. 枚举。 你不可以inheritance它,但编译器可以。
  2. java.util.concurrent下的很多东西都可以在没有JVM支持的情况下实现,但是效率会差很多。

所有的Number类都以Autoboxing的forms有一点魔力。

由于提到了重要的课程 ,我将提到一些接口:

Iterable接口(自1.5开始) – 它允许一个对象参与到一个foreach循环中:

 Iterable<Foo> iterable = ...; for (Foo foo : iterable) { } 

Serializable接口有一个非常特殊的含义,与标准接口不同。 你可以定义方法,即使它们没有在接口中定义(如readResolve() )也会被考虑。 transient关键字是影响Serializable实现者行为的语言元素。

  1. 抛出,RuntimeException,错误AssertionError
  2. 参考 WeakReference,SoftReference,PhantomReference
  3. 枚举
  4. 注解

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支持。)

“新”和“抛”指示如何初始化这些内部结构的行为是什么/特别的。

注释和数字几乎全是怪异的。