Class 对象
Class类是java中很重要的对象,它记录一个类的类型信息。每一个类都对应了一个Class对象,也就是我们java编译后生成的.class文件。
类在什么时候加载
java中的类都是动态加载。动态链接就是java最大的一个特性。除了final类和static类其余类都是动态加载的。即只有在第一次使用到这个类,或者创建第一个对这个类的静态成员的引用是时,就会加载这个类。
必要时才会加载
如何获取Class对象
static Class.forName(类全名包括包名) //返回与给定字符串名称的类或接口关联的类对象。注意抛出异常
// 类字面常量 安全且简单,编译期检查对象
// 创建了Class对象引用的时候,不会自动初始化该Class对象
类名.class
Class对象的一些其他方法
Class.getInterfaces() // 获取一个Class对象,它包含你所感兴趣的对象的接口
Class.getName() // 获取包全名
Class.getSimlpleName() // 仅仅获取类名
isInterface() // 判断是不是接口
T newInstance() // 创建由该类对象表示的类的新实例,必须要带有默认构造器
Class<?>[] getClasses() // 返回一个数组,其中包含表示所有公共类和接口的类对象,这些公共类和接口是由该类对象表示的类的成员。
实用类以前的准备工作
加载:类加载器执行,查看字节码,并从这些字节码中创建Class对象
链接:验证 类中的字节码,为静态域分配存储空间,如果必需的话,将解析这个类创建对其他类的引用
初始化:具有超类,则初始化,执行静态初始化器和初始化模块
下面几个代码说明问题,这里我们利用静态代码块来看类是什么时候初始化的,static代码块可以看到类是在什么时候初始化的。
class InitTime {
static {
System.out.println("class init");
}
static final int staticOne = 17;
static final int staticTwo = ClassInitalization.rand.next(1000); // 这里采用的是随机初始,并不是编译期常量。这里会触发类的初始化。所以也不是final和static修饰的变量就会在编译期初始化。
public static void main(String[] arg) {
System.out.println(InitTime.staticOne);
// 下面会触发类的初始化
System.out.println(InitTime.staticTwo);
}
}
类型转换前先做检查
我们可以通过使用 instanceof 来对对象进行检查,告诉我们对象是否是某个特定类型的实例。
使用类字面常量
动态的instanceof
递归计数
反射:运行时的类信息
一些场景使得我们不得不使用 ”运行时的类信息“,比如:基于构建的编程、可视化编程方法(通过拖动控件然后设置属性)。
如何未知对象进行操作
Class 类和java.lang.reflect(Field . Method . Constructor)类库为对反射的概念进行了支持。
反射通过这些类库与一个未知对象进行打交道,来在运行时校验.class文件。而RTTI是在编译期检测.class文件,这也是他们之间最大的不同。
类方法提取器
如何快速得到一个类中定义的方法或被覆盖的方法。
动态代理
InvovationHandler