GH1995 / articles

blog
https://gh1995.github.io
2 stars 0 forks source link

Java反射 #26

Open GH1995 opened 4 years ago

GH1995 commented 4 years ago

反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。

GH1995 commented 4 years ago

Class类

JVM为每个加载的classinterface创建了对应的Class实例来保存classinterface的所有信息;

获取一个class对应的Class实例后,就可以获取该class的所有信息;

通过Class实例获取class信息的方法称为反射(Reflection);

JVM总是动态加载class,可以在运行期根据条件来控制加载class

GH1995 commented 4 years ago

访问字段

Java的反射API提供的Field类封装了字段的所有信息:

通过Class实例的方法可以获取Field实例:getField()getFields()getDeclaredField()getDeclaredFields()

通过Field实例可以获取字段信息:getName()getType()getModifiers()

通过Field实例可以读取或设置某个对象的字段,如果存在访问限制,要首先调用setAccessible(true)来访问非public字段。

通过反射读写字段是一种非常规方法,它会破坏对象的封装。

GH1995 commented 4 years ago

调用方法

Java的反射API提供的Method对象封装了方法的所有信息:

通过Class实例的方法可以获取Method实例:getMethod()getMethods()getDeclaredMethod()getDeclaredMethods()

通过Method实例可以获取方法信息:getName()getReturnType()getParameterTypes()getModifiers()

通过Method实例可以调用某个对象的方法:Object invoke(Object instance, Object... parameters)

通过设置setAccessible(true)来访问非public方法;

通过反射调用方法时,仍然遵循多态原则。

GH1995 commented 4 years ago

调用构造方法

Constructor对象封装了构造方法的所有信息;

通过Class实例的方法可以获取Constructor实例:getConstructor()getConstructors()getDeclaredConstructor()getDeclaredConstructors()

通过Constructor实例可以创建一个实例对象:newInstance(Object... parameters); 通过设置setAccessible(true)来访问非public构造方法。

GH1995 commented 4 years ago

获取继承关系

image

GH1995 commented 4 years ago

动态代理

Java标准库提供了动态代理功能,允许在运行期动态创建一个接口的实例;

动态代理是通过Proxy创建代理对象,然后将接口方法“代理”给InvocationHandler完成的。