繁体   English   中英

什么是 Class 对象(java.lang.Class)?

[英]what is the Class object (java.lang.Class)?

Class的 Java 文档说:

Class对象在加载类时由 Java 虚拟机自动构造,并通过调用类加载器中的defineClass方法来defineClass

这些Class对象是什么? 它们与通过调用new从类实例化的对象相同吗?

另外,例如object.getClass().getName()如何将所有内容都类型转换为超类Class ,即使我没有从java.lang.Class

没有任何东西被类型转换为Class Java 中的每个Object都属于某个class 这就是为什么所有其他类都继承的Object类定义了getClass()方法的原因。

getClass()或类字面量 - Foo.class返回一个Class对象,其中包含有关该类的一些元数据:

  • 姓名
  • 方法
  • 领域
  • 构造函数
  • 注释

以及一些有用的方法,如转换和各种检查( isAbstract()isPrimitive()等)。 javadoc准确地显示了您可以获得关于类的哪些信息。

因此,例如,如果您的方法被赋予一个对象,并且您希望处理它以防它使用@Processable批注进行批注,则:

public void process(Object obj) {
    if (obj.getClass().isAnnotationPresent(Processable.class)) {
       // process somehow; 
    }
}

在此示例中,您获取有关给定对象的类的元数据(无论它是什么),并检查它是否具有给定的注释。 Class实例上的许多方法被称为“反射操作”,或简称为“反射。 阅读这里关于反射,为什么以及何时使用它。

另请注意, Class对象表示正在运行的 Java 应用程序中的枚举和接口以及类,并具有相应的元数据。

总而言之 - java 中的每个对象都有(属于)一个类,并且有一个各自的Class对象,其中包含有关它的元数据,可以在运行时访问。

Class 对象是一种描述对象类的元对象。 它主要与 Java 的反射功能一起使用。 您可以将其视为实际类的“蓝图”。 例如,你有一个像这样的类 Car:

public class Car {
    public String brand;
}

然后,您可以构造一个 Class 对象来描述您的“Car”类。

Class myCarClass = Class.forName("Car");

现在,您可以对该 Class 对象上的 Car 类进行各种查询:

myCarClass.getName() - returns "Car"
myCarClass.getDeclaredField("brand") - returns a Field object describing the "brand" field

等等。 每个 java 对象都有一个 getClass() 方法,它返回描述 Java 对象的 Class 的 Class 对象。 所以你可以这样做:

Car myCar = new Car();
Class myCarClass  = myCar.getClass();

这也适用于您不知道的对象,例如您从外部获得的对象:

public void tellMeWhatThisObjectsClassIs(Object obj) {
    System.out.println(obj.getClass().getName());
}

您可以将此方法提供给任何 java 对象,它会打印您提供给它的对象的实际类。

在使用 Java 时,大多数时候您不需要担心 Class 对象。 不过,他们有一些方便的用例。 例如,它们允许您以编程方式实例化某个类的对象,这通常用于对象序列化和反序列化(例如,在 XML 或 JSON 之间来回转换 Java 对象)。

Class myCarClass = Class.forName("Car");
Car myCar = myCarClass.newInstance();  // is roughly equivalent to = new Car();

您还可以使用它来查找类的所有声明字段或方法等,这在某些情况下非常有用。 因此,例如,如果您的方法得到一个未知对象并且您需要了解更多关于它的信息,例如它是否实现了某些接口等,那么 Class 类就是您的朋友。

长话短说,java.lang.reflect 包中的 Class、Field、Method 等类允许您分析定义的类、方法、字段,创建它们的新实例,调用方法等各种东西它们允许您在运行时动态执行此操作。

getClass()是一种返回一个对象的方法,该对象是java.lang.Class一个实例......不涉及强制转换。 铸造看起来像这样:

Class<?> type = (Class<?>) object;

我还想添加到 ColinD 的答案中,即 getClass 将为相同类型的实例返回相同的对象 这将打印true

    MyOtherClass foo = new MyOtherClass();
    MyOtherClass bar = new MyOtherClass();
    System.out.println(foo.getClass()==bar.getClass());

请注意,它不是equals ,我使用的是==

Class 对象是 Class (java.lang.Class) 的一个实例。 下面从类的 javadoc 引用应该回答你的问题

类没有公共构造函数。 相反,Java 虚拟机在加载类时以及通过调用类加载器中的 defineClass 方法时自动构造 Class 对象。

为了完全理解类对象,让我们回过头来了解一下我们首先得到了类对象。 你看,你创建的每个.java文件,当你编译那个.java文件时,jvm 会创建一个.class文件,这个文件包含关于这个类的所有信息,即:

  1. 类的全限定名
  2. 班级家长
  3. 方法信息
  4. 变量字段
  5. 构造函数
  6. 修饰符信息
  7. 常量池

您在上面看到的列表是您在典型课程中通常看到的列表。 现在,到目前为止,您的.java文件和.class文件存在于您的硬盘上,当您实际需要使用该类时,即在main()方法中执行代码时,jvm 将在您的硬盘中使用该.class文件驱动并将其加载到 jvm 中的 5 个内存区域之一,即方法区,在将.class文件加载到方法区后,jvm 将立即使用该信息和表示该类存在于堆中的 Class 对象内存区。

这是顶层视图,

.java --compile--> .class -->当你执行你的脚本时--> .class加载到方法区--jvm从方法区创建类对象-->一个类对象诞生了

使用类对象,您可以获得诸如类名和方法名等关于类的所有信息。

还要记住,您在脚本中使用的每个类只能有一个类对象。

希望这是有道理的

Object类默认是java中所有类的父类。 换句话说,它是java的最顶级类。

如果您想引用任何您不知道其类型的对象,则 Object 类很有用。 请注意,父类引用变量可以引用子类对象,称为向上转换。

让我们举个例子,有 getObject() 方法返回一个对象,但它可以是任何类型,如 Employee、Student 等,我们可以使用 Object 类引用来引用该对象。 例如:

Object obj=getObject() ;//我们不知道这个方法会返回什么对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM