많은 주류 프레임워크는 리플렉션 기술을 사용합니다. 예를 들어, ssh 프레임워크는 구성 파일로서의 xml + 리플렉션 기술이라는 두 가지 기술을 사용합니다.
Reflection과 관련된 클래스 패키지입니다.
java.lang.reflect.* 및 java.lang.Class;
Java의 모든 유형(기본 유형 포함)은 Class 객체에 해당하며 이 클래스는 java.lang.Class입니다. 즉, 각 유형에는 Class에 해당하는 Class 객체가 있습니다. Class에는 공용 생성자가 없습니다. 공개 액세스가 없는 것은 아닙니다.
클래스 객체를 얻는 방법
다음과 같이 코드 코드를 복사합니다 .
.각 object.getCalss()에 대해 해당 클래스를 가져올 수 있습니다.
.Class.forName(String), String 작성 방법: 패키지 이름.클래스 이름. 패키지 이름.클래스 이름에 해당하는 객체가 생성됩니다. 참고: 1.2는 참조 유형에만 적용됩니다.
.기본 유형의 경우: 캡슐화 클래스. TYPE은 해당 기본 유형의 클래스 객체를 나타냅니다. 참고: 3은 기본 유형에만 적용됩니다.
.유형, 클래스. <유형 4는 보편적입니다.>
위의 네 가지 방법 중 방법 2만이 동적입니다. 패키지를 변경하면 됩니다. 따라서 동적 프로그래밍을 실제로 구현하려면 방법 2만 사용하면 됩니다.
각 유형에는 하나의 Class 객체만 있습니다. 즉, 주소는 하나만 있지만 유형이 다르면 다릅니다.
따라서 다음 인쇄 결과는 모두 사실입니다.
다음과 같이 코드 코드를 복사합니다 .
//쌍 및 참조 유형
클래스 c1 = "".getClass();
클래스 c2 = Class.forName("java.lang.String");
클래스 c3 = String.class;
System.out.println(c1 ==c2);//true
//기본 유형의 경우
클래스 num1 = Integer.TYPE;
클래스 번호2 = int.class;
System.out.println(num1 == num2);//true
클래스 멤버의 관련 메소드를 얻기 위한 리플렉션
[<매개변수 유형에 따라> 구조 가져오기] (일반적으로 선언하지 않고 사용함)
다음과 같이 코드 코드를 복사합니다 .
생성자<T> getConstructor(Class<?>... 매개변수 유형)
이 Class 객체가 나타내는 클래스의 지정된 공용 생성자를 반영하는 생성자 객체를 반환합니다.
생성자<?>[] getConstructors()
이 Class 객체가 나타내는 클래스의 모든 공용 생성자를 반영하는 생성자 객체가 포함된 배열을 반환합니다.
생성자<T> getDeclaredConstructor(Class<?>... 매개변수 유형)
이 Class 객체가 나타내는 클래스 또는 인터페이스에 대해 지정된 생성자 메서드를 반영하는 생성자 객체를 반환합니다.
생성자<?>[] getDeclaredConstructors()
이 Class 객체가 나타내는 클래스가 선언한 모든 생성자 메서드를 반영하는 생성자 객체의 배열을 반환합니다.
[<속성 이름에 따라> 속성 가져오기] (속성은 일반적으로 비공개이므로 일반적으로 선언과 함께 사용됩니다)
다음과 같이 코드 코드를 복사합니다 .
필드 getField(문자열 이름)
이 Class 객체가 나타내는 클래스 또는 인터페이스의 지정된 공용 멤버 필드를 반영하는 Field 객체를 반환합니다.
필드[] getFields()
이 Class 객체가 나타내는 클래스 또는 인터페이스의 액세스 가능한 모든 공용 필드를 반영하는 Field 객체가 포함된 배열을 반환합니다.
필드 getDeclaredField(문자열 이름)
이 Class 객체가 나타내는 클래스 또는 인터페이스의 지정된 선언 필드를 반영하는 Field 객체를 반환합니다.
필드[] getDeclaredFields()
이 Class 객체가 나타내는 클래스 또는 인터페이스에 의해 선언된 모든 필드를 반영하는 Field 객체의 배열을 반환합니다.
[메서드 가져오기 <메서드 이름과 매개변수 유형>] (보통 선언하지 않고 사용함)
다음과 같이 코드 코드를 복사합니다 .
메소드 getMethod(문자열 이름, 클래스<?>... 매개변수 유형)
이 Class 개체가 나타내는 클래스 또는 인터페이스의 지정된 공용 멤버 메서드를 반영하는 Method 개체를 반환합니다.
메소드[] getMethods()
이 Class 객체가 나타내는 클래스 또는 인터페이스(해당 클래스 또는 인터페이스에 의해 선언된 멤버와 슈퍼클래스 및 슈퍼인터페이스에서 상속된 멤버 포함) 메서드의 공용 멤버를 반영하는 Method 객체가 포함된 배열을 반환합니다.
메소드 getDeclaredMethod(문자열 이름, 클래스<?>... 매개변수 유형)
이 Class 객체가 나타내는 클래스 또는 인터페이스의 지정된 선언 메서드를 반영하는 Method 객체를 반환합니다.
메소드[] getDeclaredMethods()
공용, 보호, 기본(패키지) 액세스 및 전용 메서드를 포함하여 이 Class 개체가 나타내는 클래스 또는 인터페이스에서 선언한 모든 메서드를 반영하지만 상속된 메서드는 제외하는 Method 개체의 배열을 반환합니다.
T newInstance()
이 Class 객체가 나타내는 클래스의 새 인스턴스를 만듭니다. <new Instance()는 동적으로 객체를 생성할 수 있습니다.>
문자열 toString()
객체를 문자열로 변환합니다.
알아채다: newInstance()는 매개변수 없는 생성자를 호출합니다. 클래스에 매개변수 없는 생성자가 없는 경우 newInstance()는 예외를 생성합니다.
선언된 메서드는 비공개성을 지원하지만 상속은 지원하지 않습니다. 선언되지 않은 메서드는 상속을 지원하지만 비공개성을 지원하지 않으며 공개 항목만 꺼낼 수 있습니다.
따라서 속성은 일반적으로 선언과 함께 선언됩니다. 속성은 일반적으로 비공개이고 메서드는 일반적으로 선언 없이 획득되며 생성자는 일반적으로 선언 없이 획득됩니다.
인스턴스 시뮬레이션 리플렉션은 클래스에서 관련 속성과 메서드를 얻습니다.
리플렉션을 사용하여 속성에 값 할당
현장의 방법
객체 get(객체 obj)
지정된 객체에서 이 필드가 나타내는 필드의 값을 반환합니다.
필드 f = c.getXXField(속성 이름);
값 = f.get(객체);
void set(객체 obj, 객체 값)
지정된 개체 변수에서 이 Field 개체가 나타내는 필드를 지정된 새 값으로 설정합니다.
f.set(객체, 값);
클래스<?> getType()
이 Field 객체가 나타내는 필드의 선언된 유형을 식별하는 Class 객체를 반환합니다.
속성 유형을 가져오는 데 사용됩니다(Class 객체 반환).
다음과 같이 코드 코드를 복사합니다 .
클래스 c = Student.class;
Object obj = c.newInstance(); //Student 클래스의 객체 생성
Field f = c.getDeclaredField("name"); //이름 속성 가져오기
f.setAccessible(true); //비공개 액세스를 설정합니다.
f.set(obj, "장산");
System.out.println(f.get(obj)); //obj의 name 속성 값을 가져옵니다.
리플렉션을 사용하여 구문 호출 생성자에 대한 실제 호출은 newInstance() 메서드가 호출될 때입니다.
다음과 같이 코드 코드를 복사합니다 .
클래스 c = Class.forName("com.clazz.reflect.Student");
생성자 con = c.getConstructor(); //생성이 수행되지 않습니다.
Object cObj = c.getConstructor().newInstance();//매개변수 없는 생성자 호출
생성자 conAll = c.getConstructor(int.class,String.class,int.class);
Object caobj = conAll.newInstance(1001,"zjamgs",234235);//매개변수를 사용하여 생성자를 호출합니다.
System.out.println(caobj); //출력 인쇄
리플렉션을 사용하여 메서드 호출 Object.메소드 이름(값 1,2,3);
메소드 m = c.getMethoed(메소드 이름, 매개변수 유형...);
m.invoke(객체, 메소드 호출 매개변수) 기본 메소드에 필요한 형식 매개변수가 0인 경우 제공된 args 배열의 길이는 0 또는 null일 수 있습니다.
다음과 같이 코드 코드를 복사합니다 .
클래스 c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); //Sutdent 객체를 생성합니다.
Method msetName = c.getMethod("setName", String.class);//obj는 유형을 변환할 필요가 없습니다.
msetName.invoke(obj, "zhangsan");//setName 메소드를 호출하고 매개변수를 전달합니다.
메소드 msetId = c.getMethod("setId", int.class);
msetId.invoke(obj, 409090202);
System.out.println(obj);
반사 적용 예시 엔터티 클래스
다음과 같이 코드 코드를 복사합니다 .
패키지 org.dennisit.reflect.entity;
import java.io.Serialized;
/**
*
*사용자.java
*
* @version: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">이메일 보내기</a>
*
* @since: 1.0 생성시간: 2013-2-26 01:43:56 pm
*
* TODO: User.java 클래스는 ...에 사용됩니다.
*
*/
공개 클래스 사용자가 직렬화 가능{을 구현합니다.
개인 문자열 테스트;
public void excute(문자열 이름, int age){
System.out.println("name=" + 이름 + ",age=" + 나이);
}
}
반사 테스트 수업
다음과 같이 코드 코드를 복사합니다 .
패키지 org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
*
* ReflectEx.java
*
* @version: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">이메일 보내기</a>
*
* @since: 1.0 생성시간: 2013-2-26 01:46:00 pm
*
* TODO: ReflectEx.java 클래스는 ...에 사용됩니다.
*
*/
공개 클래스 ReflectEx {
public static void main(String[] args)throws 예외 {
클래스 cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); //사용자 객체 생성
Field f = cls.getDeclaredField("test"); //테스트 속성 가져오기
f.setAccessible(true); //비공개 속성 테스트를 위한 공개 접근 권한
f.set(obj, "zhangsan"); //테스트를 위해 다시 복사합니다.
System.out.println(f.get(obj)); //obj의 테스트 속성 값을 가져옵니다.
//메소드 이름을 기반으로 메소드를 가져옵니다.
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoke(obj, "dennisit",23); //실행 메소드 호출
}
}
수술 효과
다음과 같이 코드 코드를 복사합니다 .
장산
이름=데니스트,나이=23
반사형 동적 인스턴스화 클래스 작성 예
다음과 같이 코드 코드를 복사합니다 .
패키지 org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
java.util.Map 가져오기;
import java.util.Set;
/**
*
* DynamicReflect.java
*
* @version: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">이메일 보내기</a>
*
* @since: 1.0 생성시간: 2013-2-26 01:58:12 pm
*
* TODO: 리플렉션을 사용한 동적 인스턴스화의 예
*
*/
공개 클래스 DynamicReflect {
공용 정적 객체 getInstance(String className,Map<String,Object> map)에서 예외 발생{
클래스 c = Class.forName(className);
객체 obj = c.newInstance(); //객체 객체
Set<String> 키 = map.keySet(); //해당 속성을 모두 가져옵니다.
Field[] fAll = c.getDeclaredFields(); //클래스의 모든 속성을 가져옵니다.
for(int i=0;i<fAll.length;i++){
for(String key:keys){ //루프 매칭
if(fAll[i].getName().equals(key)){ //사용자가 전달한 속성이 획득한 클래스의 속성 이름과 일치하는 경우
필드 f = c.getDeclaredField(key);//이 속성 가져오기
//setXxx() 메소드 이름 구성
String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
Method method = c.getMethod(methodName, f.getType());//구성된 사용자 이름을 기반으로 해당 메소드를 가져옵니다.
method.invoke(obj, map.get(key));//메서드 호출
}또 다른{
계속하다;
}
}
}
반환 객체;
}
}
다음으로 우리가 작성한 동적 반사 인스턴스화 예제를 테스트합니다.
엔터티 클래스
다음과 같이 코드 코드를 복사합니다 .
패키지 org.dennisit.reflect.entity;
import java.io.Serialized;
/**
*
*사용자.java
*
* @version: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">이메일 보내기</a>
*
* @since: 1.0 생성시간: 2013-2-26 01:43:56 pm
*
* TODO: 엔터티 클래스
*
*/
공개 클래스 사용자가 직렬화 가능{을 구현합니다.
개인 문자열 이름;
비공개 연령;
개인 문자열 이메일;
public User() { //매개변수 생성자가 없어야 합니다.
}
//getter() 및 setter()
}
주요 시험 수업
다음과 같이 코드 코드를 복사합니다 .
패키지 org.dennisit.reflect.main;
java.util.HashMap 가져오기;
java.util.Map 가져오기;
org.dennisit.reflect.entity.User 가져오기;
/**
*
* ReflectEx.java
*
* @version: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">이메일 보내기</a>
*
* @since: 1.0 생성시간: 2013-2-26 01:46:00 pm
*
* TODO: ReflectEx.java 클래스는 ...에 사용됩니다.
*
*/
공개 클래스 ReflectEx {
public static void main(String[] args)throws 예외 {
클래스 cls = Class.forName("org.dennisit.reflect.entity.User");
문자열 className = "org.dennisit.reflect.entity.User";
Map<String,Object> map = new HashMap<String, Object>();
map.put("이름", "dennisit");
map.put("나이", 22);
map.put("email", "[email protected]");
사용자 user = (User)DynamicReflect.getInstance(className, map);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
}
}
프로그램 실행 결과
다음과 같이 코드 코드를 복사합니다 .