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

时间:2010-12-15 18:10:24

标签: java class inheritance

Class的Java文档说:

  

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

这些Class对象是什么?它们是否与通过调用new

从类中实例化的对象相同

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

7 个答案:

答案 0 :(得分:81)

没有任何内容被Class所取代。 Java中的每个Object都属于某个class。这就是为什么Object类(由所有其他类继承)定义getClass()方法。

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

  • 名称
  • 方法
  • 字段
  • 构造
  • 注释

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

因此,例如,如果您的方法被赋予了一个对象,并且您希望在使用@Processable注释进行注释的情况下对其进行处理,那么:

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

在此示例中,您将获取有关给定对象的类的元数据(无论它是什么),并检查它是否具有给定的注释。 Class实例上的许多方法称为“反射操作”,或简称为“反射。Read here关于反射,使用的原因和时间。

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

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

答案 1 :(得分:40)

Class对象是一种描述对象类的元对象。它主要用于Java的反射功能。您可以将其视为实际课程的“蓝图”。例如。你有这样一个类汽车:

public class Car {
    public String brand;
}

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

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对象。他们有一些方便的用例。例如。它们允许您以编程方式实例化特定类的对象,这些对象通常用于对象序列化和反序列化(例如,将Java对象转换为XML并返回,主要是返回)。

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

您还可以使用它来查找您的类的所有声明的字段或方法等,这在某些情况下非常有用。所以例如如果你的方法被传递给一个未知的对象并且你需要了解它的更多信息,比如它是否会影响某些界面等,那么Class类就是你的朋友。

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

答案 2 :(得分:8)

getClass()返回作为java.lang.Class实例的对象的方法...不涉及任何转换。铸造看起来像这样:

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

答案 3 :(得分:5)

我还想向ColinD的回答添加getClass将为相同类型的实例返回相同对象。这将打印 true

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

请注意,它不是等于,我使用 ==

答案 4 :(得分:3)

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

  

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

答案 5 :(得分:1)

默认情况下,Object类是Java中所有类的父类。换句话说,它是Java的最高级类。

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

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

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

答案 6 :(得分:1)

为了完全理解类对象,让我们回到前面并了解我们首先获得了类对象。您会看到,每创建一个.java文件,当编译该.java文件时,jvm都会创建一个.class文件,该文件包含有关该类的所有信息,即:

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

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

这是顶层视图,

.java-编译-> .class->执行脚本时-> .class加载到方法区域中--jvm从方法区域创建类对象- >类对象诞生

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

请记住,脚本中使用的每个类都应该只有一个类对象。

希望这很有意义