反射是什么
- Java的反射机制是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
- 通俗说,反射就是程序在运行的时候能够“观察”并且修改自己的行为,是程序对自身的反思、自检、修改
- 在编译的时候知道类或对象的具体信息,就可以直接对其进行操作,这是外部对程序进行的一个”思考“及操作。如果在编译时不知道类或对象的具体信息,就要用反射,如果类的名字放在了XML文件中,就需要在运行时读取XML文件,动态获取类信息
反射的作用是什么
通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁,可以给程序带来极大的灵活性。
反射可以创建对象,操作属性,调用方法
创建对象
1.通过Class的newInstance()方法
2.通过Constructor的newInstance()方法
操作属性
通过Class对象的getFields()或者getField()方法可以获得该类所包括的全部Field属性或指定Field属性。Field类提供了以下方法来访问属性
- getXxx(Object obj):获取obj对象该Field的属性值。
- getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
- getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
- 同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。
调用方法
- 通过Class对象的getMethods() 方法可以获得该类所包括的全部方法, 返回值是Method[]
- 通过Class对象的getMethod()方法可以获得该类所包括的指定方法, 返回值是Method
- 每个Method对象对应一个方法,获得Method对象后,可以调用其invoke() 来调用对应方法
- Object invoke(Object obj,Object [] args):obj代表当前方法所属的对象的名字,args代表当前方法的参数列表,返回值Object是当前方法的返回值,即执行当前方法的结果。
反射的应用——实现注解
实现一个自己的注解
定义注解
package reflect.reflect2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: gyj
* @description:自写注解
* @date: 2023/9/4 11:09
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
String value() default "gyj";
}
声明方法 通过反射拿到参数
package reflect.reflect2;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author: gyj
* @description
* @date: 2023/9/4 13:06
*/
public class ReflectProcessor {
public void parseMethod(final Class<?> clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
final Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[] {});
final Method[] methods = clazz.getDeclaredMethods();
for (final Method method : methods) {
final TestAnnotation testAnnotation = method.getAnnotation(TestAnnotation.class);
if (testAnnotation != null){
method.invoke(obj,testAnnotation.value());
}
}
}
}
测试类
package reflect.reflect2;
import java.lang.reflect.InvocationTargetException;
/**
* @author: gyj
* @description
* @date: 2023/9/4 13:07
*/
public class Test {
@TestAnnotation
public static void sayHello(final String value){
System.out.println("====> name " + value);
}
@TestAnnotation(value="xw")
public static void sayHelloToSomeone(final String value){
System.out.println("====> name " + value);
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException {
final ReflectProcessor reflectProcessor = new ReflectProcessor();
reflectProcessor.parseMethod(Test.class);
}
}