- 反射概念:"反"是相对于"正"而言的,通常情况下,如果我们想要使用某个类中的方法首先需要知道是哪个类,然后new一个类对象,通过创建的对象去调用相应的方法。而反射机制则是允许在程序运行过程中,根据Class对象或者一个具体的类对象就可以获取整个类的结构信息(构造器、属性、方法等)。
- 反射作用:可以通过Class对象(字节码对象,.class文件被加载到内存时创建)进行一系列类及其对象所拥有的操作(调用方法、属性赋值等)。
package main.java.per.learning.reflection;
import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
public class MyReflection {
@Test
public void getClassTest() throws ClassNotFoundException {
Class c1 = Class.forName("main.java.per.learning.reflection.User");
User user = new User();
Class c2 = user.getClass();
Class c3 = User.class;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
}
@Test
public void classTypeTest(){
Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = Override.class;
Class c6 = ElementType.class;
Class c7 = Integer.class;
Class c8 = void.class;
Class c9 = Class.class;
System.out.println("c1:" + c1);
System.out.println("c2:" + c2);
System.out.println("c3:" + c3);
System.out.println("c4:" + c4);
System.out.println("c5:" + c5);
System.out.println("c6:" + c6);
System.out.println("c7:" + c7);
System.out.println("c8:" + c8);
System.out.println("c9:" + c9);
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
@Test
public void getClassInfoTest()
throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException,
InstantiationException, IllegalAccessException {
Class c1 = Class.forName("main.java.per.learning.reflection.User");
System.out.println("===================类的名字===================");
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
System.out.println("===================类的属性===================");
Field[] fields = c1.getFields();
Field hobby = c1.getField("hobby");
System.out.println(hobby);
for (Field field : fields) {
System.out.println("getFields:" + field.getName());
}
Field name = c1.getDeclaredField("name");
System.out.println(name);
Field[] declaredFields = c1.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("getDeclaredFields:" + declaredField);
}
System.out.println("===================类的方法===================");
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println("getMethods:" + method);
}
Method[] declaredMethods = c1.getDeclaredMethods();
for(Method declaredMethod : declaredMethods){
System.out.println("getDeclaredMethods:" + declaredMethod);
}
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
System.out.println("===================类的构造器===================");
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println("getConstructors:" + constructor);
}
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println("getDeclaredConstructors:" + constructor);
}
Constructor constructor1 = c1.getConstructor(String.class, int.class, String.class);
System.out.println(constructor1);
Constructor constructor2 = c1.getDeclaredConstructor(String.class);
System.out.println(constructor2);
constructor2.setAccessible(true);
User user1 = (User)constructor2.newInstance("张三");
System.out.println(user1);
}
@Test
public void manipulateClassTest()
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException,
IllegalAccessException {
Class c1 = Class.forName("main.java.per.learning.reflection.User");
Constructor constructor = c1.getDeclaredConstructor();
User user = (User)constructor.newInstance();
Method testFunc = c1.getDeclaredMethod("testFunc", String.class);
testFunc.setAccessible(true);
testFunc.invoke(user, "测试方法调用");
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(user, "张三");
Method setHobby = c1.getDeclaredMethod("setHobby", String.class);
setHobby.invoke(user, "橄榄球");
System.out.println(user);
}
}