获取Class对象的三种方式

xiaoxiao2021-02-28  116

一、Java中的Class对象

众所周知,java一切皆对象。但是如果平时注重业务开发,而比较少关注很多开源框架如Spring、Hibernate等的源码,我们一般会比较少看到Class对象的身影。今天我们就来看看这个神秘的Class对象。

二、什么是Class对象?

每个类都对应一个Class对象。虽然我们一般不会直接操作这个对象,其实这个对象非常常见,我们Java文件编译后的class文件,保存的就是这个类的Class对象。 我们定义了几个类,我们就能看到编译后的目录(通常在target目录)下有几个class文件。 1.比如我们定义一个Employee类,那么我们就看到有一个Employee.class文件;

package com.sky.javase; public class Employee { }

2.比如我们定义一个public的Book类,和一个BookMark类,那么就得到两个class文件:Book.class、BookMark.class

package com.sky.javase; public class Book { } class BookMark{ }

3.比如我们定义一个Person类和一个内部类Head,那么也得到两个class文件:Person.class、Person$Head.class(尤其注意内部类的命名规则)

package com.sky.javase; public class Person { class Head{ } }

总之:一个萝卜一个坑,定义几个类,就有几个class文件。这些class文件,保存的就是我们定义类的Class对象。当这个类的Class对象被加载到内存,它就被用来创建这个类的所有对象。、

三、如何获得Class对象?

根据实际情况,我们可以有多种方式获取。 在示例开始前,我们定义了一个类Student,分别写了一个静态代码块和一个构造代码块。当类被加载就会调用静态代码块,当创建对象,就会调用构造代码块。我们通过输出来观察三种方式的差异。

class Student{ static{ System.out.println("这是静态代码块!"); } { System.out.println("这是构造代码块!"); } }

1.如果你刚好有一个实例对象,直接调用它的getClass方法(继承至Object):

public class ReflectTest { @Test public void reflect_getClass(){ Student stu = new Student(); Class<?> sClass = stu.getClass(); } }

输出结果: 这是静态代码块! 这是构造代码块!

2.如果没有实例对象,只有类,可以直接通过类的字面常量class获取:

public class ReflectTest { @Test public void reflect_class(){ Class<?> clz = Student.class; } }

输出结果:无任何输出!

3.特殊情况下,我们在编码时不知道具体的类或实例,那么我们可以通过Class的forName静态方法:

public class ReflectTest { @Test public void reflect_forName(){ try { Class<?> clz = Class.forName("com.sky.javase.Student"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }

输出结果: 这是静态代码块!

获取某个类的Class对象可以有多种方式。但“巧妇难为无米之炊”,不管上面三种方式的哪一种,都需要和这个类密切相关的东西,要么类的一个实例对象,要么是这个类,要么是类的完全限定名(包名+类名,类加载器会去类路径下找)。

转载请注明原文地址: https://www.6miu.com/read-18980.html

最新回复(0)