为了区别于我们常用的Class,因此给了个中文名类类型。目的就是为了知道此Class非彼Class。上一篇博客已经介绍了Class Loader,它的作用是根据提供的信息来加载类到内存中。我之前有提过这个类信息的提供者就是本篇博客要介绍的Class。提醒:一个类的Class对象和它的Instance是不一样的,切记,不然你会混乱的。开始了!
概念
Class类是所有类(注意是对象)的共有信息的抽象,比如该类实现的接口、对应的加载器、类名等等。一句话,类类型保存了每个类所对应的类型信息。每一个类都有一个Class对象,这个对象在类被加载后由JVM自动构造。也是由JVM管理的,Class类是没有公共的构造方法的。
Class对象对于类来说就像是,DNA对于每个人,里面有你的一切生物信息。java中可以通过Class来取得类的实例,也许将来的将来通过你的DNA也能得到你的另一个实例。科幻电影里是已经实现了。ok,概念应该有个初步的认识了。
常用方法
方法的介绍本来不应该这么简单,但是发现一句两句的说不清楚,并且对于Java的理解有很好的帮助。所以临时决定这部分单独的写一篇博客。这里就简单的列几个,之前用过的方法。
- forName:返回与带有给定字符串名的类或接口相关联的 Class 对象。
- getName():一个Class对象描述了一个特定类的属性,Class类中最常用的方法getName以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
- newInstance():创建Class对象描述的类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。
- getClassLoader():返回该类的类加载器。
- getInterfaces():确定此对象所表示的类或接口实现的接口。
- getComponentType():返回表示数组组件类型的 Class。
- getSuperclass():返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class对象
- isArray():判定此 Class 对象是否表示一个数组类。
怎么得到
获得Class对象的方法有三种
(1)利用Object.getClass()方法获取该对象的Class实例;
(2)使用Class.forName()静态方法,用类的名字获取一个Class实例
(3)运用类的.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
这里需要注意的是虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。也就是说Class对象只会有一个。看如下代码:
测试类
public class Test { static { System.out.println("静态初始化"); } { System.out.println("非静态初始化"); } }
客户端
public class client { public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{ //方法1 Class c=Class.forName("com.zjj.ClassTest.Test"); //方法2 c=Test.class; //方法3 Test t=new Test(); c=t.getClass(); Test t2=new Test(); } }
输出结果为:
静态初始化
非静态初始化
非静态初始化
大家知道静态初始化方法是在类加载的时候执行的,非静态初始化方法是在类被实例化的时候执行的。而输出结果只打印了一次“静态初始化”,这就说明三次得到的Class对象都是同一个。
也就是说,在运行期间,如果我们要产生某个类的对象或者的得到某个类的Class对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象
结语
本篇总结:至此,应该可以理解了Class也是一个类,只不过它是所有类的一个抽象,名字又和我们所知道的Class一样容易造成混淆。总的来说,每一个类都有对应的一个Class对象来保存这个类的信息,这个Class对象由JVM构造和管理。Class对象的存在是Java反射的基础。
反射机制总结:反射机制是Java的一个重要的内容,为Java提供了运行时加载类的能力,也就是动态性。Class是信息提供者,Class Loader是加载工具,二者都是反射机制最基础的部分。那么所谓的反射就是解除耦合,方式就是通过Class取得未知类的信息,而后实例化。当然Class Loader的所做的工作是隐藏的,是Class对象去调用的。所以无需显示的自己调用。那么,三篇博客至此结束了!
对了,从这篇博客里引出的内容,还得额外加一篇博客,内容已经和反射机制没有太大的联系但是有助于加深对Java运行机制的理解。