1. Class类
1)除了基本数据类型外,其他类型都是class(包括interface),class的本质也是数据类型(Type)。
2)JVM每次动态加载时,会创建一个Class类型的实例,并在实例中保存所有的class信息,包括包名、类名、字段、方法等,因此获取了某个Class实例就可以通过这个Class实例获取到该实例对应的class的所有信息。
3)通过Class实例获取class信息的方法称为反射。
4)获取class的Class实例
a. 通过静态变量class。
Class cls = String.class;
b. 通过getClass()方法。
Class cls = "Hello".getClass();
c. 通过静态方法 Class.forName()方法,里面写class的完整类名。
Class cls = Class.forName("java.lang.String");
5)获取到同一个实例可以用==比较。
6)动态加载:JVM在执行java程序时,并不是一次性把所有用到的类都加载到内存,第一次需要用到时才加载。
2. 访问字段
1)通过Class实例的方法可以获取Field实例。
2)通过Class实例获取字段Field对象的方式。
getField(name):根据字段名获取某个public的字段名(包括父类)
getDeclaredField(name):根据字段名获取当前类的某个field包括private(不包括父类)
getFields():获取所有public的field(包括父类)
getDeclaredFields():获取当前类的所有field包括private(不包括父类)
3)Java的反射API提供的Field实例封装了字段的所有信息。
getModifiers():字段修饰符:private、public
getType():字段类型:String、int
getName():字段名称:name、score
4)通过反射读写字段是一种非常规方法,它会破坏对象的封装性。
3. 调用方法
1)通过Class实例的方法可以获取Method实例。
2)通过Class实例获取方法Method实例的方式。
getMethod(name, Class...):获取某个public的Method(包括父类)
getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
getMethods():获取所有public的Method(包括父类)
getDeclaredMethods():获取当前类的所有Method(不包括父类)
3)Java的反射API提供的Method实例封装了方法的所有信息。
getModifiers():方法的修饰符:public、private
getReturnType():方法的返回值类型:int、string.class
getName():方法名称:getName()
getParameterTypes():方法的参数类型:int、string.class
4)获取到方法后调用方法,使用invoke调用,第一个参数是对象实例,即在哪个实例上调用该方法,后面的可变参数要和方法参数一致,
静态方法调用,不需要传实例,第一个参数永远传null。
5)通过反射调用方法时,仍然遵循多态的规则。
4. 调用构造方法
1)Java的反射API提供的Constructor实例封装了构造方法的所有信息。
2)可以调用Class.newInstance()创建实例,只能调用该类的public无参构造方法。
3)通过Class实例获取构造方法Constructor对象的方式
getConstructor(Class...):获取某个public的Constructor;
getDeclaredConstructor(Class...):获取某个Constructor;
getConstructors():获取所有public的Constructor;
getDeclaredConstructors():获取所有Constructor。
5. 获取继承关系
getSuperclass():获取继承的父类
getInterfaces():获取实现的接口