类型信息
类在什么时候加载到JVM中
所有的类都是在对其第一次使用时,动态加载到JVM中。当程序创建第一个对类的静态成员的引用时,就会加载这个类。这个证明构造器也是类的静态方法,即使在构造器之前并没有使用static关键字。因此,使用new操作符创建类的新对象也会被当作对类的静态成员的引用。简而言之,就是当对一个类的静态成员持有引用时,这个类就会被加载到JVM。
如何通过Class对象来创建其他对象
Class c = Class.forName("com.leibown.Demo"); /*可以通过class的对象的newInstance方法来创建新的实例,会得到Object引用,而这个引用指向的是Demo对象*/ Object obj = c.newInstance();
注:使用newInstance()来创建的类,必须带有默认的构造器(无参构造方法)。
使用”.class”来创建对Class对象的引用所包含的三个步骤
- 加载,这是由类加载器执行的。这个步骤将查找字节码(通常在classpath所指定的路径中查找,但这并非是必需的),并从这些字节码中创建一个Class对象。
- 链接。在链接阶段将验证类中的字节码,为静态域分配储存空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
- 初始化。如果该类如有超类,则对其初始化,执行静态初始化器和静态初始化块。
泛化的Class引用
Class intClass = int.class; Class<Integer> genericIntClass = int.class;
为了在使用泛化的Class引用时放松限制,加入了通配符,它是Java泛型中的一部分。通配符就是”?“,表示”任何事物“。
Class<?> intClass = int.class; intClass = double.class;//普通的类引用可以被重新赋值为指向任何其他的Class对象
为了创建一个Class引用,它被限定为某种类型,或该类型的任何子类型,你需要将通配符与extends关键字相结合,创建一个范围。
Class<? extends Number> bounded = int.class; bounded = double.class; bounded = Number.class;
当你将泛型语法用于Class对象时,newInstance()将返回该对象的确切类型。
Class<SmallDemo> smallDemoClass = SmallDemo.class; SmallDemo smallDemo = smallDemoClass.newInstance(); Class<? super SmallDemo> demo = smallDemoClass.getSuperClass(); Object obj = demo.newInstance();
类型转换cast()
进行向下转型前,如果没有其他信息可以告诉你这个对象是什么类型,那么使用instanceof是非常重要的,否则会得到一个ClassCastException异常。
if(x instanceof Dog) ((Dog)x).bark();