反射的基本使用方法
Java反射用的很多,像Retrofit趁怔、Dagger湿硝、Hook、插件化等等很多地方都有用到润努,掌握J(rèn)ava反射的使用十分必要关斜,了解反射原理就更好了。這里就簡(jiǎn)單的介紹下反射的基本用法铺浇。
先把Student.class貼一下
@ClassAnnotation(value = 20)
public class Student {
@FieldAnnotation
public static int staticFiled;
public static final int FINAL_FILED = 100;
private String name;
public int age;
@ConstructorAnnotation(value = 40)
public Student() {
}
private Student(int age) {
this.age = age;
System.out.println("Constructor age!");
}
private Student(String name) {
this.name = name;
System.out.println("Constructor name!");
}
public Student(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Constructor name & age!");
}
public String getName() {
return name;
}
@MethodAnnotation
public void setName(String name) {
this.name = name;
System.out.println("invoke public Method!");
}
private int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
System.out.println("invoke private Method!");
}
public static void staticMethod() {
System.out.println("invoke static Method!");
}
}
三種反射方法
//方式一
try {
Class<?> clazz1 = Class.forName("com.example.myapplication.reflection.Student");
System.out.println("Class.forName: " + clazz1.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//方式二
Class<Student> clazz2 = Student.class;
System.out.println("Student.class: " + clazz2.getName());
//方式三
Student student = new Student();
Class<? extends Student> clazz3 = student.getClass();
System.out.println("student.getClass(): " + clazz3.getName());
獲取構(gòu)造器
Student student = new Student();
Class<? extends Student> clazz3 = student.getClass();
System.out.println("student.getClass(): " + clazz3.getName());
//獲取所有的構(gòu)造器
Constructor<?>[] constructors = clazz3.getDeclaredConstructors();
System.out.print("get all Constructors");
for (Constructor<?> constructor : constructors) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
System.out.print("parameters length: " + parameterTypes.length);
System.out.print(" constructor Modifier: " + Modifier.toString(constructor.getModifiers()));
for (Class<?> clazz : parameterTypes) {
System.out.print(" " + clazz.getName());
}
System.out.print("\n");
}
//獲取public的構(gòu)造器
constructors = clazz3.getConstructors();
System.out.print("get public Constructors");
for (Constructor<?> constructor : constructors) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
System.out.print("parameters length: " + parameterTypes.length);
System.out.print(" constructor Modifier: " + Modifier.toString(constructor.getModifiers()));
for (Class<?> clazz : parameterTypes) {
System.out.print(" " + clazz.getName());
}
System.out.print("\n");
}
//獲取指定參數(shù)的構(gòu)造器
Class<?>[] parameters = {int.class};
Constructor<?> constructor;
try {
System.out.print("get public Constructors");
constructor = clazz3.getDeclaredConstructor(parameters);
System.out.println("constructor Modifier: " + Modifier.toString(constructor.getModifiers()));
constructor.setAccessible(true);
constructor.newInstance(11);
} catch (Exception e) {
e.printStackTrace();
}
執(zhí)行結(jié)果:
get all Constructors
parameters length: 2 constructor Modifier: public java.lang.String int
parameters length: 1 constructor Modifier: private java.lang.String
parameters length: 1 constructor Modifier: private int
parameters length: 0 constructor Modifier: public
get public Constructors
parameters length: 2 constructor Modifier: public java.lang.String int
parameters length: 0 constructor Modifier: public
get public Constructors
constructor Modifier: private
Constructor age!
反射字段
Student student = new Student("大白", 1);
Class<? extends Student> clazz3 = student.getClass();
Field[] fields = clazz3.getDeclaredFields();
System.out.print("fields length: " + fields.length);
for (Field field : fields) {
System.out.print("field Modifier: " + Modifier.toString(field.getModifiers()));
System.out.print(" " + field.getName());
}
fields = clazz3.getFields();
System.out.print("fields length: " + fields.length);
for (Field field : fields) {
System.out.print("field Modifier: " + Modifier.toString(field.getModifiers()));
System.out.print(" " + field.getName());
}
try {
Field field = clazz3.getDeclaredField("FINAL_FILED");
System.out.println("fields FINAL_FILED value: " + field.get(null));
field = clazz3.getDeclaredField("name");
field.setAccessible(true);
System.out.println("fields name value: " + field.get(student));
field.set(student, "小白");
System.out.println("fields name value: " + field.get(student));
} catch (Exception e) {
e.printStackTrace();
}
執(zhí)行結(jié)果:
fields length: 4
field Modifier: public static staticFiled
field Modifier: public static final FINAL_FILED
field Modifier: private name
field Modifier: public age
fields length: 3
field Modifier: public static staticFiled
field Modifier: public static final FINAL_FILED
field Modifier: public age
fields FINAL_FILED value: 100
fields name value: 大白
fields name value: 小白
Constructor name & age!
這里使用了反射修改了name字段的值痢畜,并使用field.setAccessible(true);修改了name字段的訪問(wèn)權(quán)限
反射方法
Student student = new Student("大白", 1);
Class<? extends Student> clazz3 = student.getClass();
System.out.println("get all methods");
Method[] methods = clazz3.getDeclaredMethods();
System.out.println("methods length: " + methods.length);
for (Method method : methods) {
Class<?>[] parameterTypes = method.getParameterTypes();
System.out.print("method name: " + method.getName());
System.out.print(" method Modifier: " + Modifier.toString(method.getModifiers()));
System.out.print(" parameters length: " + parameterTypes.length);
for (Class<?> clazz : parameterTypes) {
System.out.print(" " + clazz.getName());
}
}
methods = clazz3.getMethods();
System.out.println("methods length: " + methods.length);
for (Method method : methods) {
Class<?>[] parameterTypes = method.getParameterTypes();
System.out.print("method name: " + method.getName());
System.out.print(" method Modifier: " + Modifier.toString(method.getModifiers()));
System.out.print(" parameters length: " + parameterTypes.length);
for (Class<?> clazz : parameterTypes) {
System.out.print(" " + clazz.getName());
}
}
try {
Class<?>[] parameters = {int.class};
Method method = clazz3.getDeclaredMethod("setAge", parameters);
method.setAccessible(true);
System.out.println("fields age value: " + student.age);
method.invoke(student, 20);
System.out.println("fields age value: " + student.age);
} catch (Exception e) {
e.printStackTrace();
}
try {
Method method = clazz3.getDeclaredMethod("staticMethod");
method.setAccessible(true);
method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
執(zhí)行結(jié)果:
get all methods
methods length: 5
method name: getName method Modifier: public parameters length: 0
method name: setName method Modifier: public parameters length: 1 java.lang.String
method name: staticMethod method Modifier: public static parameters length: 0
method name: getAge method Modifier: private parameters length: 0
method name: setAge method Modifier: private parameters length: 1 int
methods length: 12
method name: getName method Modifier: public parameters length: 0
method name: setName method Modifier: public parameters length: 1 java.lang.String
method name: staticMethod method Modifier: public static parameters length: 0
method name: wait method Modifier: public final native parameters length: 1 long
method name: wait method Modifier: public final parameters length: 2 long int
method name: wait method Modifier: public final parameters length: 0
method name: equals method Modifier: public parameters length: 1 java.lang.Object
method name: toString method Modifier: public parameters length: 0
method name: hashCode method Modifier: public native parameters length: 0
method name: getClass method Modifier: public final native parameters length: 0
method name: notify method Modifier: public final native parameters length: 0
method name: notifyAll method Modifier: public final native parameters length: 0
fields age value: 1
invoke private Method!
fields age value: 20
invoke static Method!
這里需要注意的是clazz3.getMethods返回的長(zhǎng)度是12,包括父類Object中的public方法
反射注解
Student student = new Student();
Class<? extends Student> clazz3 = student.getClass();
Annotation[] annotations = clazz3.getDeclaredAnnotations();
System.out.println("annotations length: " + annotations.length);
for (Annotation annotation : annotations) {
if (annotation instanceof ClassAnnotation) {
System.out.println("annotations name: " + ((ClassAnnotation) annotation).value());
}
Class<? extends Annotation> clazz = annotation.annotationType();
System.out.print("annotations Modifier: " + Modifier.toString(clazz.getModifiers()));
}
//獲取指定參數(shù)的構(gòu)造器
Class<?>[] parameters = {};
try {
Constructor<?> constructor = clazz3.getDeclaredConstructor(parameters);
annotations = constructor.getDeclaredAnnotations();
System.out.println("annotations length: " + annotations.length);
for (Annotation annotation : annotations) {
if (annotation instanceof ConstructorAnnotation) {
System.out.println("annotations name: " + ((ConstructorAnnotation) annotation).value());
}
Class<? extends Annotation> clazz = annotation.annotationType();
System.out.print("annotations Modifier: " + Modifier.toString(clazz.getModifiers()));
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
執(zhí)行結(jié)果:
annotations length: 1
annotations name: 20
annotations Modifier: public abstract interface
annotations length: 1
annotations name: 40
annotations Modifier: public abstract interface
這里補(bǔ)上自定義注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassAnnotation {
int value() default 1;
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CONSTRUCTOR)
public @interface ConstructorAnnotation {
int value() default 1;
}
其他注解的使用和上面類似,這里就不做分享了。