什么是反射?
问题1:
1.对象有编译类型和运行类型
Object obj = new Data();
编译类型:Object
运行类型(其实就是obj对象真实的类型):Data
需求:根据对象obj调用Data类中一个的方法:toLocalString,如何来做?
obj.toLocalString();不能调用,编译过程中就会去编译类型Object中检查是否有该方法,若没有,编译失败
解决方法1:强制转换obj为Data类型,前提:必须知道对象的真实类型是什么?
Data d = (Data)obj;
d.toLocalString(); //YES
如果我不知道obj的真实类型,那又如何去调用toLocalString方法,如何去做?
问题2:
类是用来描述对象的;或者说是描述数据的数据;
对象三个特性:封装(例如参数可以封装在一个对象里面,直接传递进去调用)、继承、多态;
万物皆对象:
从概念分析那么类也应该是一种对象;
新的问题,既然类是一种对象,那么谁又来描述该对象呢?
而我们又说描述对象的都是类。
元数据:matadata描述数据的描述数据
反射:得到元数据的过程
既然Class是对一切类共同功能行为和状态的抽象,那么Class中应该有类具备的成员;
getPackage()表示类的包
getSuperClass()表示类的父类
getMethods()表示类的所有方法
getField()表示类的所有字段
通过反射就可以得到一个类中的包、类名、父类、字段、方法、构造器...
但是前提必须知道,你反射的是哪一个类...
Class类和Class实例
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class类;
对比提问:众多的人用一个什么类表示?众多的Java类用一个什么类表示?
人》Person
Java类》Class
对比提问:Person类代表人,它的实例对象就是张三、李四这样一个个具体的人,Class类代表Java类,它的各个实例对象又分别对应什么呢?
对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码等等;
一个类被加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的;
一个类在虚拟机中只有一份字节码;
Class类:由于描述一切类/接口(枚举就是一个特殊的类;注释是一种接口)
Class实例:就是指JVM中的一份字节码
问题:那Class实例到底表示的是哪一份字节码?
为了明确区分出Class实例表示的是谁的字节码,Class类提供了泛型
Class<Data> clz1 = Data.class;//clz1表示的是Data的字节码
Class<String> clz2 = String.class;//clz2表示的是String的字节码
如何得到Class的实例:
1.类名.class(就是一份字节码)
Class<User> clz1 = User.class;
2.Class.forName(String className)