从以下版本开始:JDK1.0
从以下版本开始:JDK1.0
从以下版本开始:JDK1.5
类对象: 在Java中,类是是对具有一组相同特征或行为的实例的抽象并进行描述,对象则是此类所描述的特征或行为的具体实例。作为概念层次的类,其本身也具有某些共同的特性,如都具有类名称、由类加载器去加载,都具有包,具有父类,属性和方法等。于是,Java中有专门定义了一个类,Class,去描述其他类所具有的这些特性,因此,从此角度去看,类本身也都是属于Class类的对象。
当一个类在被加载的时候虚拟机就会自动的生成一个这个类的一个Class类型的“类对象”,每个类都对应着一个这样的类对象。
Java运行时系统一直对所有的对象进行所谓的运行时类型标识,记录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
我们都知道所有的java类都是继承了object这个类,在object这个类中有一个方法:getclass() 这个方法是用来取得该类已经被实例化了的对象的该类的引用,这个引用就是指向的是Class类的对象。
所有的类都是在对其第一次使用时,动态加载到JVM中的。当程序创建第一个对类的静态成员的引用时,就会加载这个类,使用new操作符创建类的新对象也会被当作对类的静态成员的引用。
因此Java在开始运行前并不会去加载类,其各个部分是在必须时才加载的。
类加载器首先检查这个类的Class对象是否已经加载,如果尚未加载,默认的类加载器就会根据类名查找.class文件。在这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并不包含不良Java代码。
一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象
以下这些方法都是获取已加载的值,即某个类对应的Class对象已经在堆中生成以后,我们通过不同方式获取对这个Class对象的引用。
而通过类装载器中的 defineClass 方法生成才是真正将字节码加载到虚拟机的方法,会在堆中生成新的一个Class对象。
Class obj1 = Class.forName("java.lang.Integer");
Integer integer = new Integer(100);
Class obj2 = integer.getClass();
// 获取该类的父类的类型
Class obj2Parent = obj2.getSuperclass();
Class obj3 = Integer.class;
注意:使用类字面常量获取类对象不会引起静态初始化
生成的是object类的实例,需要类型转换
Class objClass1 = Class.forName("java.lang.String");
String s = (String) objClass1.newInstance();
利用泛型,直接生成目标实例
Class<String> objClass2 = String.class;
String s = objClass2.newInstance();

所以当我们获取字面常量的Class引用时,触发的应该是加载阶段,因为在这个阶段Class对象已创建完成,获取其引用并不困难,而无需触发类的最后阶段初始化。
这很像一个先有鸡还是先有蛋的问题,众所周知:
一切类都继承自己Object,Class也是类,所以Class也会继承自Object
一切类都是Class的实例(类对象),Object也是类,所以Object也会是Class类的一个实例
那么到底Object和Class执行的先后顺序是怎样的呢?
事实是:这些相互依赖的核心类型完全可以在“混沌”中一口气都初始化好,然后对象系统的状态才叫做完成了“bootstrap”,后面就可以按照Java对象系统的一般规则去运行。JVM、JavaScript、Python、Ruby等的运行时都有这样的bootstrap过程。
在“混沌”(boostrap过程)里,JVM可以为对象系统中最重要的一些核心类型先分配好内存空间,让它们进入已分配空间但尚未完全初始化状态。此时这些对象虽然已经分配了空间,但因为状态还不完整所以尚不可使用。
然后,通过这些分配好的空间把这些核心类型之间的引用关系串好。到此为止所有动作都由JVM完成,尚未执行任何Java字节码。然后这些核心类型就进入了完全初始化状态,对象系统就可以开始自我运行下去,也就是可以开始执行Java字节码来进一步完成Java系统的初始化了。
getGenericInterfaces():Type[]
在泛型还没出现之前,描述类的类型是Class,随着语言的优化,泛型的出现,而Class又无法描述泛型,故而出现了其余四种对于涉及泛型的描述。
String s、String s1[]、List list等对应的类型均是Class类型。List s1 、Map map 等对应的类型均是ParameterizedType类型List s[] 、Map map[] 等对应的类型均是GenericArrayType类型,而List s[]、Map map[]是Class类型HashMap中的 K,VList extends Object> 中?对应的类型
getRawType(): Type
该方法的作用是 返回当前的ParameterizedType的类型。如一个List,返回的是List的Type,即返回当前参数化类型本身的Type。
getOwnerType(): Type
返回ParameterizedType类型所在的类的Type。如Map.Entry
getActualTypeArguments(): Type[]
该方法返回参数化类型<>中的实际参数类型, 如 Map
注意: 该方法只返回最外层的<>中的类型,无论该<>内有多少个<>。
getBounds(): Type[]getName(): StringgetGenericDeclaration():TypegetGenericComponentType(): Type
返回组成泛型数组的实际参数化类型,如 List[] 则返回 List。
注意:无论从左向右有几个[ ]并列,这个方法仅仅脱去最右边的[ ]之后剩下的内容就作为这个方法的返回值。
getLowerBounds():Type[]getUpperBounds(): Type[]