1,元数据存储
1)类信息在方法区(
image.pngPerm代
),Class对象在堆中方法区中有Class对象的引用。
2)Class类中包含的反射数据信息
image.png
2,基础
1)JVM加载class文件时,读入二进制字节流,将静态存储结构转化成方法区运行时数据结构,并
image.png在堆中创建一个对应的java.lang.Class对象,作为方法区这些数据的访问入口
2)Class对象包含了与类有关的信息,是类型信息在运行时的表示。
反射机制,对于任意一个类,在运行时,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它任意一个方法,访问任意属性。
3)要想在运行时使用类型信息,必须获取在堆中该Class对象的引用。
Class.forName("全名")加载类,并初始化类
在Perm方法区存储类信息,在堆中创建Class对象,返回Class对象的引用。
Base.class 使用类的static class属性,触发类的加载,不会初始化类
,任何数据类型(包含基本类型)都有一个static的class属性。
Object#public final native Class<?> getClass(); 通过已实例化的对象获取Class对象的引用
4)反射:运行时打开和检查.class文件
,运行时获得对象和类型的信息,动态加载类,动态访问以及调用目标类型的字段,方法以及构造函数。
5)通过obj.getClass()方法可以在运行时获得对象的信息,并且能访问对象的字段。Field[] fields = clazz.getDeclaredFields()
3,反射常用操作
java.lang.reflect包中,常用Class、Constructor、Field、Method等类。
image.png
1)通过反射获取构造函数
getDeclaredConstructors()all the constructors declared by the class
getConstructors()all the public constructors of the class
image.png
getContructor(Class<?>... parameterTypes)specified public constructor of the class
image.png
getDeclaredConstructor(Class<?>... parameterTypes)specified constructor of the class
image.png
2)通过构造函数创建实例。Constructor-->newInstance(Object... initargs)
public T newInstance(Object ... initargs)constructor.newInstance("123", "456"); constructor.newInstance(null) 无参构造
底层还是使用native方法,private static native Object newInstance0(Constructor<?> var0, Object[] var1)
3)反射获取类的成员变量并访问
Field[] fields = clazz.getDeclaredFields();all the fields
Field[] fields = clazz.getFields();public fields
Field field = clazz.getField("nickname");specified public member field
Field field = clazz.getDeclaredField("nickname");the specified declared field
field.setAccessible(true);
解除私有限制
Class clazz = Account.class;
Account account = clazz.newInstance();
Field field = clazz.getDeclaredFiled("username");
field.setAccessible(true);
field.set(account, "hzq");
Filed类中set方法。public void set(Object obj, Object value)
obj the object whose field should be modified
value the new value for the field of obj
4)获取成员方法并调用。
Method[] method = clazz.getMethods();all the public methods
Method[] method = clazz.getDeclaredMethods()all the declared methods
Method method = clazz.getMethod(String name, Class<?>... parameterTypes);方法名和参数类型列表, specified public method
Method method = clazz.getDeclaredMethod(String name, Class<?>... parameterTypes);specified declared method
MyClass obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("privatePrint", String.class);
method.setAccessible(true);
method.invoke(obj, "halo 你好");
Method的public Object invoke(Object obj, Object... args)方法。
obj the object the underlying method is invoked from 调用谁的方法用谁的对象,如果方法是静态的,可以传null
args the arguments used for the method call
Class clazz = Integer.class;
Method method = clazz.getMethod("valueOf", String.class);
System.out.println((Integer)method.invoke(null, "123"));
网友评论