基础 | Class类详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bingbeichen/article/details/83615857

Object类中的getClass()方法即返回一个Class类型的实例,那么 「Class类到底是什么?从何而来?又有什么作用呢?」


参考答案

Class类是什么?

先来简单了解一下Java虚拟机中类的加载过程:

「加载」阶段是「类加载」过程的第一个阶段,虚拟机需要完成以下三件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流(.class文件即保存着类的二进制数据)。
  2. 将该字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在Java堆中生成一个代表该类的java.lang.Class对象,作为方法区中该数据结构的访问入口。

也就是说,Class是一个保存着运行时类所有信息的类,即在程序运行时跟踪类且掌握着类的全部信息,故其也被称为反射的源头(有点儿小抽象)。

如何获取Class类对象?

共有四种方式来获取Class类的实例,如下:

@Test
// 需要提供异常处理
public void test() throws ClassNotFoundException{
	//1.通过运行时类的.class属性获取
	Class<Person> clazz1 = Person.class;
	System.out.println(clazz1);
	
	//2.通过运行时类的对象获取
	Person p = new Person();
	Class clazz2 = p.getClass();
	System.out.println(clazz2.getName());
	
	//3.通过Class类的静态方法获取
	String className = "com.whutqbchen.java.Person";
	Class clazz3 = Class.forName(className);
	System.out.println(clazz3);
	
	//4.通过类的加载器获取
	ClassLoader cl = this.getClass().getClassLoader();
	Class clazz4 = cl.loadClass(className);
	System.out.println(clazz4.getName());
}

提示:在启动时,包含main方法的类被加载。它会加载所有需要的类。这些被加栽的类又要加载它们需要的类,以此类推。对于一个大型的应用程序来说,这将会消耗很多时间,用户会因此感到不耐烦。可以使用下面这个技巧给用户一种启动速度比较快的幻觉。不过,要确保包含main方法的类没有显式地引用其他的类。首先,显示一个启动画面;然后,通过调用Class.forName手工地加载其他的类。

Class类的实例可以做什么?

获取到运行时类的Class实例后,通过Class类的实例可以:

  • 通过newInstance()方法创建对应运行类的对象。
  • 获取其对应类的完整结构,如构造器、属性、方法、内部类、父类、所在的包、异常和注解等。
  • 调用对应的运行时类的指定结构,如属性、方法和构造器。
  • 反射的应用,即动态代理(又挖一坑)。

所以说,Class类是反射的源头,有一种「Class在手天下我有」的既视感。

这也是Java中「反射」技术的主要内容。

注意事项:

请注意,一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如,int不是类,但int.class是一个Class类型的对象。

另外,调用Class类实例的newInstance()方法动态创建类对象时,需要对应的运行时类中有空参的构造器,这个细节本人在面试Synopsys的时候被问到过。


源码阅读

通过Class类的实例获取运行时类的所有描述信息的代码较长,在此仅给出对应的方法描述,如下:

通过反射可访问的主要描述信息


推荐阅读


欢迎关注

Java名企面试吧,每天10点24分,我们不见不散!

丙子先生的宗旨是,每天以短篇幅讲高频面试题,不增加太多负担,但需要持之以恒。

能力有限,欢迎指教!

猜你喜欢

转载自blog.csdn.net/bingbeichen/article/details/83615857