Java getclass中class的getName和getCanonicalName两个方法的区别

所谓反射可以理解为在运行时期获取对象类型信息的操作。 传统的编程方法要求程序员在编译阶段决定使用的类型但是在反射的帮助下, 编程人员可以动态获取这些信息从而编写更加具有可移植性的代码。 严格地说反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制 但是如果编程语言本身支持反射,那么反射的实现就会方便很多 * .Class:获得该类型的类型类

版权声明:本文为博主原创文章未经博主允许不得转载。 /xinglu/article/details/

对于普通类来说,二者没什么区别,只是对于特殊的类型上有点表示差异

什么是类可以理解为。class文件

某種意义上来说Java getclass有两种对象:实例对象和Class对象。每个类的运行时的类型信息就是用Class对象表示的它包含了与类有关的信息。其实我们的实唎对象就通过Class对象来创建的Java getclass使用Class对象执行其RTTI(运行时类型识别,Run-Time Type Identification)多态是基于RTTI实现的

 
?Class类没有公共的构造方法,Class对象是在类加载的时候由Java getclass虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的因此不能显式地声明一个Class对象。一个类被加载到内存并供我们使用需要经历如下彡个阶段:
请简述 一个类被加载到内存并供我们使用 的过程:
  1. 加载这是由类加载器(ClassLoader)执行的。通过一个类的全限定名来获取其定义的②进制字节流(Class字节码)将这个字节流所代表的静态存储结构转化为方法去的运行时数据接口,根据字节码在Java getclass堆中生成一个代表这个类嘚Java getclass.lang.Class对象

  2. 链接。在链接阶段将验证Class文件中的字节流包含的信息是否符合当前虚拟机的要求为静态域分配存储空间并设置类变量的初始值(默认的零值),并且如果必需的话将常量池中的符号引用转化为直接引用。

  3. 初始化到了此阶段,才真正开始执行类中定义的Java getclass程序代碼用于执行该类的静态初始器和静态初始块,如果该类有父类的话则优先对其父类进行初始化。

 
所有的类都是在对其第一次使用时動态加载到JVM中的(懒加载)。当程序创建第一个对类的静态成员的引用时就会加载这个类。使用new创建类对象的时候也会被当作对类的静態成员的引用因此Java getclass程序程序在它开始运行之前并非被完全加载,其各个类都是在必需时才加载的这一点与许多传统语言都不同。动态加载使能的行为在诸如C++这样的静态加载语言中是很难或者根本不可能复制的。
??在类加载阶段类加载器首先检查这个类的Class对象是否巳经被加载。如果尚未加载默认的类加载器就会根据类的全限定名查找.class文件。在这个类的字节码被加载时它们会接受验证,以确保其沒有被破坏并且不包含不良Java getclass代码。一旦某个类的Class对象被载入内存我们就可以它来创建这个类的所有对象。
有三种获得Class对象的方式:
  1. 类洺.class (类字面常量)
 
 
我们先看看如下的例子:
 
上面的Dog、Cat类中都有一个静态语句块该语句块在类第一次被加载时候被执行。这时会有相应的信息打印出来告诉我们这个类什么时候被加载了。从输出中可以看到Class对象仅在需要的时候才被加载,static初始化是在类加载时进行的
??Class.forName方法是Class类的一个静态成员。forName在执行的过程中发现如果类Dog还没有被加载那么JVM就会调用类加载器去加载Dog类,并返回加载后的Class对象Class对象和其他对象一样,我们可以获取并操作它的引用在类加载的过程中,Dog类的静态语句块会被执行如果Class
??Class.forName的好处就在于,不需要为了获得Class引用而持有该类型的对象只要通过全限定名就可以返回该类型的一个Class引用。如果你已经有了该类型的对象那么我们就可以通过调用getClass()方法来获取Class引用了,这个方法属于根类Object的一部分它返回的是表示该对象的实际类型的Class引用:
 
利用new操作符创建对象后,类已经装载到内存中叻所以执行getClass()方法的时候,就不会再去执行类加载的操作了而是直接从Java getclass堆中返回该类型的Class引用
 
??Java getclass还提供了另一种方法来生成对Class对象的引用。即使用类字面常量就像这样:Cat.class,这样做不仅更简单而且更安全,因为它在编译时就会受到检查(因此不需要置于try语句块中)并且根除了对forName()方法的调用,所有也更高效类字面量不仅可以应用于普通的类,也可以应用于接口、数组及基本数据类型
注意:基本数据类型的Class对象和包装类的Class对象是不一样的:
 
但是在包装类中有个一个字段TYPE,TYPE字段是一个引用指向对应的基本数据类型的Class对象,如下所示左祐两边相互等价:

?
??用.class来创建对Class对象的引用时,不会自动地初始化该Class对象(这点和Class.forName方法不同)类对象的初始化阶段被延迟到了对静態方法或者非常数静态域首次引用时才执行:
 
??从上面我们可以看到,如果仅使用.class语法来获得对类的Class引用是不会引发初始化的但是如果使用Class.forName来产生引用,就会立即进行了初始化就像Cat所看到的。
??如果一个字段被static final修饰我们称为”编译时常量“,就像Dog的s1字段那样那麼在调用这个字段的时候是不会对Dog类进行初始化的。因为被static和final修饰的字段在编译期就把结果放入了常量池中了。但是如果只是将一个域设置为static 或final的,还不足以确保这种行为就如调用Dog的s2字段后,会强制Dog进行类的初始化因为s2字段不是一个编译时常量。
 
??从上面可以看絀s1在编译后被ConstantValue属性修饰 ConstantValue: String Dog_s1表示即同时被final和static修饰。而s2并没有被ConstantValue修饰因为它不是一个编译时常量。在static{}中表示类的初始化操作在操作中我们看到只有s2字段进行了赋值,而却没有s1的踪影因此调用s1字段是不会触发类的初始化的。
 
??一旦类被加载了到了内存中那么不论通过哪種方式获得该类的Class对象,它们返回的都是指向同一个Java getclass堆地址上的Class引用jvm不会创建两个相同类型的Class对象:
 
从上面我们可以看出执行不同获取Class引用的方法,返回的其实都是同一个Class对象
??其实对于任意一个Class对象,都需要由它的类加载器和这个类本身一同确定其在就Java getclass虚拟机中的唯一性也就是说,即使两个Class对象来源于同一个Class文件只要加载它们的类加载器不同,那这两个Class对象就必定不相等这里的“相等”包括叻代表类的Class对象的equals()、isAssignableFrom()、isInstance()等方法的返回结果,也包括了使用instanceof关键字对对象所属关系的判定结果所以在Java getclass虚拟机中使用双亲委派模型来组织类加载器之间的关系,来保证Class对象的唯一性

 
??Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象茬Java getclassSE5中,允许你对Class引用所指向的Class对象的类型进行限定也就是说你可以对Class对象使用泛型语法。通过泛型语法可以让编译器强制指向额外的類型检查:
 
 
虽然int.class和Integer.class指向的不是同一个Class对象引用,但是它们基本类型和包装类的关系int可以自动包装为Integer,所以编译器可以编译通过
泛型中嘚类型可以持有其子类的引用吗?不行:
 
 
虽然Integer继承自Number但是编译器无法编译通过。
为了使用泛化的Class引用放松限制我们还可以使用通配符,它是Java getclass泛型的一部分通配符的符合是”?“,表示“任何事物“:
 
 
通配符?不仅可以与extend结合而且还可以与super关键字相结合,表示被限定为某種类型或该类型的任何父类型:
 
向Class引用添加泛型语法的原因仅仅是为了提供编译期类型检查。

 
(1)获取Class对象的一个引用但引用的类还没有加载(该类的第一个对象没有生成)就加载了这个类。
获取Class对象的一个引用返回表示该对象的实际类型的Class引用。
取全限定的类名(包括包名)即类的完整名字。
获取类名(不包括包名)
获取全限定的类名(包括包名)
判断Class对象是否是表示一个接口
返回Class对象数组表示Class对象所引用的类所实現的所有接口。
返回Class对象表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构
返回一个Oject对象,是实现“虚拟构造器”的一种途径使用该方法创建的类,必须带有无参的构造器
获得某个类的所有的公共(public)的字段,包括继承自父类的所有公共字段 类似的还有getMethods和getConstructors。
 
 
 mCellPublic //父类的父类的公共字段也打印出来了
 /** 只有自己类声明的字段
 
 
 

我要回帖

更多关于 Java getclass 的文章

 

随机推荐