代码之家  ›  专栏  ›  技术社区  ›  Marcono1234

为什么没有java.lang.Class?

  •  23
  • Marcono1234  · 技术社区  · 6 年前

    java.lang.Class 定义多个仅适用于特定类型类的方法,例如:

    为什么会有,比如说,不 ArrayClass 获取组件类型 代替方法?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Thorben Kuck    6 年前

    这似乎或多或少是一种设计选择。自从我 设计这种语言,我不能肯定地回答,但我会试图解释这一点的潜在原因。

    那么为什么没有ArrayClass来定义getComponentType方法呢?

    理解这一点的诀窍是 java.lang.Class 类与您正在编写的类不是直接等价的。此特定类仅用于在运行时表示创建的类(例如:用于反射)。

    Java-Doc of the Class (这里来自Java 7):

    类类的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组还属于一个类,该类作为一个类对象被具有相同元素类型和维数的所有数组共享。原始Java类型(boolean、byte、char、short、int、long、float和double)和关键字void也表示为类对象。

    如果您编写代码,那么您正在编写自定义类,这意味着您创建的代码就是该类。如果创建一个名为 ,这是你的课。这个 java.lang.Class类 类只能在运行时用于分析此特定对象的类。

    getClass 是在这里定义的。这意味着您可以对任何对象的任何特定细节进行内省。例如,如果对象的特定类型不是枚举,则类在调用 getEnumConstants ,则在内省实例之前必须先对其进行强制转换,这会使使用该实例更加烦人。

    第二条 java.lang.Class类 对象,表示创建的类型 lazy ,在 ClassLoader . 在引用特定类型时,类加载器检查类是否已加载,如果未加载,则加载该类。然后它创造了java.lang.Class类-对象,它表示此特定类型。然后可以使用这个类对象来创建类型的实例。

    如果java语言的java.lang.Class类,类加载器必须实例化类的正确子类型,对应于所需的子类型。如果您能够在何处创建java.lang.Class类,很快就会失控。类加载器如何知道哪个类实例连接到您的类型?您是否必须编写特定的类实例并以某种方式标记您创建的类型以使用该类实例?你可以想象这样的情景:

    public class MyType extends ... implements ... type MyClassInstance
    

    但是,如何在自定义域中填充自定义域java.lang.Class类实例?这些并发症可能是java.lang.Class类具有泛型类型,表示连接的类型。事件尽管有一百万种可能的解决方案来解决这些复杂问题,但是仍然有一个关于可用性和健壮性的争论。

    正如甲骨文所指出的 Design Goals of the Java Programming Language :

    newInstance 例如方法。您可以在这个方法中引入一个异常,有人可能会认为,构造函数抛出了一个异常,尽管它没有。这个方向与 Why doesn't Java offer operator overloading? ,这样,您实际上是重写了 new 关键字。

    获取类 可能导致任何未知类型,这可以做任何事情。

    public class Object<T extends Class> {
        public final native T getClass();
    }
    

    这是必需的,因为我们希望将某些类连接到某些对象。但是,我们没有指定如何实例化类。通常,类是通过类加载器实例化的。再次从 JavaDoc :

    这将不再可行,除非我们需要像私有构造函数这样的某些方面。此外,我们必须提供每个自定义类作为本机C++代码。

    另一种可能是,在类似这样的实现中定义getClass方法(这段代码有不同的基于泛型的问题,但同样,只是一个示例):

    public class Object {
        public <T extends Class<?>> T getClass() {...}
    }
    
    public class MyType {
        public MyClass getClass() { return new MyClass(); }
    }
    

    InvocationHandler 例如。另一个问题是,现在开发人员可以自由地决定一个类是只实例化一次还是多次,这将打破例如 Class-Based-Programming 当然还有Java语言的一些方面。

    尽管我不能肯定地回答,但我希望这能有所帮助。