Reflection은 Java 언어의 중요한 기능입니다. 우리는 클래스를 사용하기 전에 클래스 파일을 만든 다음 몇 가지 속성, 메서드 등을 작성하는 등 이미 클래스를 생성하는 경우가 많다는 것을 알고 있습니다. 정적이지만 리플렉션 메커니즘을 사용하면 클래스를 동적으로 생성할 수 있습니다. 동적으로 클래스를 생성하는 것 외에도 유사한 개체의 데이터를 동적으로 가져와 새로 생성된 클래스에 할당할 수도 있는데, 이는 복제와 다소 유사합니다. 클래스를 동적으로 생성하는 기능이 필요한 경우가 많습니다. 예를 들어 일부 비즈니스를 처리할 때 이러한 비즈니스는 약간 다르므로 처리할 때 서로 다른 클래스를 호출하기 위해 서로 다른 비즈니스 처리를 기반으로 해야 합니다. 이번에는 반사 메커니즘이 유용합니다.
다음은 JDK API의 java.lang.reflect 패키지에 대한 설명입니다.
클래스와 객체에 대한 리플렉션 정보를 얻기 위한 클래스와 인터페이스를 제공합니다. 보안 제약 조건 내에서 리플렉션을 사용하면 로드된 클래스의 필드, 메서드 및 생성자에 대한 정보에 프로그래밍 방식으로 액세스할 수 있으며 리플렉션된 필드, 메서드 및 생성자를 사용하여 객체의 기본 동등 항목에 대해 작업할 수 있습니다.
AccessibleObject를 사용하면 필수 ReflectPermission을 사용할 수 있는 경우 액세스 확인을 억제할 수 있습니다.
배열은 배열을 동적으로 생성하고 액세스하기 위한 정적 메서드를 제공합니다.
java.lang.Class와 함께 이 패키지의 클래스는 디버거, 인터프리터, 개체 검사기, 클래스 브라우저 및 대상에 액세스해야 하는 서비스(예: 개체 직렬화 및 JavaBeans)와 같은 애플리케이션의 요구 사항에 맞게 조정할 수 있습니다. 런타임 클래스의 공개 멤버 또는 특정 클래스에서 선언된 멤버를 기반으로 하는 객체입니다.
다음은 두 가지 간단한 예를 사용하여 리플렉션 사용을 보여줍니다. 먼저 Person 클래스를 만듭니다.
다음과 같이 코드 코드를 복사합니다.
패키지 테스트;
공개 클래스 사람 {
비공개 연령;
개인 문자열 이름 = "";
개인 문자열[] arr = 새 문자열[2];
공개 개인(){}
public Person(문자열 이름, int 나이){
this.name = 이름;
this.나이 = 나이;
}
공개 int getAge() {
복귀 연령;
}
공개 무효 setAge(int age) {
this.나이 = 나이;
}
공개 문자열 getName() {
이름 반환;
}
public void setName(문자열 이름) {
this.name = 이름;
}
공개 문자열[] getArr() {
반환 도착;
}
공공 무효 setArr(String[] arr) {
this.arr = arr;
}
}
예제 1: Person 클래스의 속성 및 메서드 정보를 가져옵니다. 다음과 같이 코드를 복사합니다.
개인 정적 무효 testSimpleReflect(){
String className = "test.Person";
노력하다 {
클래스 c = Class.forName(className);
Field[] 필드 = c.getDeclaredFields();
메소드[] m = c.getDeclaredMethods();
for (필드 필드 : 필드){
System.out.println(field.getName());
}
for(방법 method : m){
System.out.println(m.getClass());
}
} 잡기(ClassNotFoundException e) {
e.printStackTrace();
}
}
이는 매우 간단합니다. 실제 작업에서도 가장 많이 사용되는 패키지 경로를 통해 클래스를 얻을 수 있습니다.
예시 2: 객체 복사 코드 복사 코드는 다음과 같습니다.
@SuppressWarnings("선택 해제됨")
공개 정적 객체 복사(객체 객체)가 예외를 발생시킵니다. {
// 객체 유형을 가져옵니다.
클래스 classType = object.getClass();
System.out.println("" + classType.getName()); // 기본 생성 방법을 통해 새 객체를 생성합니다.
객체 objectCopy = classType.getConstructor(new Class[] {})
.newInstance(new Object[] {}); // 객체의 모든 속성을 가져옵니다.
필드 필드[] = classType.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
필드 필드 = 필드[i];
문자열 fieldName = field.getName();
String firstLetter = fieldName.substring(0, 1).toUpperCase(); // 속성에 해당하는 getXXX() 메서드의 이름을 가져옵니다.
String getMethodName = "get" + firstLetter + fieldName.substring(1) // 속성에 해당하는 setXXX() 메서드의 이름을 가져옵니다.
String setMethodName = "set" + firstLetter + fieldName.substring(1) // 속성에 해당하는 getXXX() 메소드를 가져옵니다.
메소드 getMethod = classType.getMethod(getMethodName,
new Class[] {}); // 속성에 해당하는 setXXX() 메서드를 가져옵니다.
메소드 setMethod = classType.getMethod(setMethodName,
new Class[] { field.getType() }); // 원본 객체의 getXXX() 메서드를 호출합니다.
객체 값 = getMethod.invoke(object, new Object[] {});
System.out.println(fieldName + ":" + value); // 복사된 객체의 setXXX() 메서드를 호출합니다.
setMethod.invoke(objectCopy, new Object[] { value });
}
objectCopy를 반환합니다.
}
리플렉션을 사용하여 개체를 복사하면 오픈 소스 시스템 BeanUtils가 이미 개체 복사본을 캡슐화했기 때문에 일반적으로 직접 수행할 필요가 없습니다. 해당 메서드를 직접 호출할 수 있지만 BeanUtils도 기반으로 한다는 점은 주목할 가치가 있습니다. 반사 메커니즘에 대한 패키지를 만듭니다.
다음은 전화입니다.
다음과 같이 코드 코드를 복사합니다.
공개 정적 무효 메인(문자열[] 인수){
사람 사람 = new 사람("톰",22);
String[] strs = new String[]{"a","b"};
person.setArr(strs);
노력하다 {
사람 p = (사람)copy(사람);
System.out.println(p.getName()+">>"+p.getAge());
for (문자열 str : p.getArr()){
System.out.println(str);
}
} 잡기(예외 e) {
e.printStackTrace();
}
// 테스트SimpleReflect();
}