기사 디렉토리
리플렉션 메커니즘-자바의 기본 핵심 부분
Java에서의 리플렉션은 프로그램이 실행될 때 멤버 속성, 멤버 메소드, 구성 메소드를 포함하여 클래스의 다양한 세부 정보를 동적으로 얻을 수 있습니다. 클래스의 속성과 메소드를 조작하기 위해 또는 프레임 워크의 영혼입니다.
1. 개체의 클래스 클래스 가져 오기
JVM은 클래스 로더를 통해 클래스의 바이트 코드 파일을 메모리에로드 한 후 해당 클래스 객체를 생성하며, 클래스 객체를 획득 한 후 다양한 작업을 수행 할 수 있으며, 클래스 객체를 획득하는 방법은 세 가지가있다.
- Class.forName () 메서드를 통해
- class.class 멤버 살펴보기
- object.getClass () 살펴보기
// method 1
Class objectClass1 = Class.forName("java.lang.Object");
// method 2
Class<Object> objectClass2 = Object.class;
//method 3
Class<? extends Object> objectClass3 = new Object().getClass();
그리고 동일한 클래스의 Class 객체를 얻기 위해 어떤 방법을 사용하더라도 동일한 객체를 얻는다는 점에 유의해야합니다.
System.out.println(objectClass1 == objectClass2);//true
System.out.println(objectClass1 == objectClass3);//true
System.out.println(objectClass2 == objectClass3);//true
2. 클래스의 멤버 개체를 가져옵니다.
클래스의 멤버 객체를 가져 오는 네 가지 방법이 있습니다.
- getField () : 공용 속성 만 얻을 수 있습니다.
- getFields () : 모든 공용 객체의 객체 배열을 가져옵니다.
- getDeclaredField () : 모든 속성을 가져올 수 있지만 public에서만 작업 할 수 있습니다.
- getDeclaredFields () : 모든 속성을 가져올 수 있지만 public에서만 작업 할 수 있습니다.
Person person = new Person(1, 2, 3, 4);
Class<? extends Person> personClass = person.getClass();
//只能获取public属性
Field variable1 = personClass.getField("variable1");
//获取所有public对象的对象数组
Field[] fields = personClass.getFields();
//通过set方法设置某个Person对象的具体值
variable1.set(person, 1);
//通过get可以获取某个Person对象的具体值
Integer value1 = (Integer) variable1.get(person);
//可以获取任意属性,但是只能对public进行操作
Field variable4 = personClass.getDeclaredField("variable4");
Field[] declaredFields = personClass.getDeclaredFields();
//通过setAccessible方法突破限制,暴力反射
variable4.setAccessible(true);
Integer value4 = (Integer) variable4.get(person);
3. 클래스의 멤버 메서드 가져 오기
클래스의 멤버 객체를 얻는 것과 유사하게 클래스의 멤버 메소드 객체를 얻는 방법은 네 가지가 있습니다.
- getMethod () : 공용 멤버 메소드 객체 가져 오기
- getMethods () : 공용 멤버 메서드 객체의 배열을 가져옵니다.
- getDeclaredMethod () : 모든 멤버 메서드 객체를 가져올 수 있지만 public에서만 작업 할 수 있습니다.
- getDeclaredMethods () : 멤버 메서드 객체의 모든 배열을 가져올 수 있지만 public에서만 작업 할 수 있습니다.
Person person = new Person(1, 2, 3, 4);
Class<? extends Person> personClass = person.getClass();
Method[] methods = personClass.getMethods();
//通过方法的名字和参数的Class类列表来获取方法对象
Method setVariable1 = personClass.getMethod("setVariable1", Integer.class);
//通过invoke方法来调用该方法.参数是调用该方法的对象,以及方法的参数列表.结果就是返回值
Void result1= (Void) setVariable1.invoke(person, 2);
Method[] declaredMethods = personClass.getDeclaredMethods();
Method privateMethod = personClass.getDeclaredMethod("privateMethod", String.class);
//同样可以通过setAccessible来突破限制,暴力反射
privateMethod.setAccessible(true);
String result2= (String) privateMethod.invoke(person, "MarkLau");
4. 클래스의 생성자 객체를 가져옵니다.
클래스의 생성자 객체를 얻는 방법은 4 가지가 있는데 너무 비슷하다면 소개하지 않겠습니다.
- getConstructor ();
- getConstructors ();
- getDeclaredConstructor ();
- getDeclaredConstructors ();
Person person = new Person();
Class<? extends Person> personClass = person.getClass();
//由于所有的构造方法名字都相同所以不需要方法名,只需要通过参数就可以进行判断
Constructor<? extends Person> constructor = personClass.getConstructor(Integer.class, Integer.class, Integer.class, Integer.class);
//调用newInstance方法,再将参数传入就可以生成一个新的对象
Person person1 = constructor.newInstance(1, 2, 3, 4);
//通过Class对象来创建的对象只能使用无参构造
Person person2 = personClass.newInstance();