思维导图
类型信息是用来在运行时获取类的信息并使用的,这就是类型信息的功能.
- 在编译期我们其实就可以获得类型信息,比如一个类的父类是什么,重写方法不能乱写,否则编译器就会报错,这就是对编译期的类型信息的使用.
- 在运行时我们也可以获得类型信息,主要通过Class对象和instanceof关键字.
Class对象
Class对象的创建有三种方法,在反射中已经讲过,这里不再重复.
Class对象可以创建对象的实例,但是只能局限于有默认构造方法的类
//测试获得Class对象的方法
public void testBuildClass() throws Exception{
//通过实例对象获得Class对象,因为反射一般要生成对象,所以不常用
Student s1 = new Student();
Class clazz1 = s1.getClass();
//通过类字面常量获得Class对象,因为必须要导入引用,所以不太常用
//通过类字面常量获得的Class对象会在使用时进行载入,是惰性的
Class clazz2 = Student.class;
//通过特殊方法获得Class对象,这是最常用的,但必须写全路径的包名
Class clazz3 = Class.forName("reflectdemo.Student");
Student student2 = (Student)clazz3.newInstance();
}
Class对象可以配合泛型使用,如果这样的话,创建的实例将不再是Object对象,而是具体的泛型对象
//使用泛型不仅可以添加编译期检查,还会让newInstance()的实例变为泛型对象,这个功能有好有坏吧.
Class<Student> clazz = Student.class;
Student student3 = clazz.newInstance();
我们可以通过比较两个类的Class对象(使用==或者equals())来比较他们是否是同一个类,缺点是不能比较继承体系.即不会检查一个类是否为另一个类的子类.
Class.isInstance方法效果同instanceof关键字完全一样
Instanceof关键字
instanceof关键字能够确认一个类是否是另一个类或者是其子类,但是使用时使用字符来表示一个类,而不是使用Class对象,所以一般使用Class.isInstance方法替代.
//测试Class.isInstance和instanceof
public void testInstanceof(){
Student student = new Student();
System.out.println(student instanceof Student);
//可以检查是否为某个类的子类
System.out.println(student instanceof Object);
//用Class.isInstance替代instanceof
System.out.println(Student.class.isInstance(student));
System.out.println(Object.class.isInstance(student));
}