자바 반사 메커니즘(1)
자바 가 실 행 될 때 환경 에서 임의의 클래스 에 대해 어떤 속성 과 방법 이 있 는 지 알 수 있 습 니까?임의의 대상 에 대해 그것 의 임의의 방법 을 호출 할 수 있 습 니까?답 은 긍정 적 이다.이러한 동적 획득 류 의 정보 와 동적 호출 대상 의 방법 은 자바 언어의 반사 에서 나온다.
1.실행 할 때 임의의 대상 이 속 한 종 류 를 판단 합 니 다.
2.운행 할 때 임의의 유형의 대상 을 구성한다.
3.실행 할 때 임의의 클래스 가 가지 고 있 는 구성원 변수 와 방법 을 판단 합 니 다.
4.실행 할 때 임의의 대상 을 호출 하 는 방법
일반적으로 개발 자 커 뮤 니 티 는 동적 언어 에 대해 대체적으로 인정 하 는 정 의 는'프로그램 이 실 행 될 때 프로그램 구조 나 변수 유형 을 바 꿀 수 있 고 이런 언어 를 동적 언어 라 고 부른다'는 것 이다.이 관점 에서 볼 때 Perl,Python,Ruby 는 동적 언어 입 니 다.C+,자바,C\#동적 언어 가 아 닙 니 다.
JDK 에서 주로 다음 과 같은 종류 로 자바 반사 메커니즘 을 실현 하 는데 이런 종 류 는 모두 java.lang.reflect 패키지 에 있다
1.Class 류:한 종 류 를 대표 합 니 다.내부 류
2.Field 클래스:대표 클래스 의 구성원 변수(구성원 변 수 는 클래스 의 속성 이 라 고도 함).
3.Method 류:대표 적 인 방법.
4.Constructor 류:대표 적 인 구조 방법.
5.Array 클래스:동적 으로 배열 을 만 들 고 배열 에 접근 하 는 요 소 를 정적 으로 만 드 는 방법 을 제공 합 니 다.
Reflection API 의 기본 작
예 1:
public class DumpMethods
{
public static void main(String args[]) throws Exception
{
//
Class<?> classType = Class.forName(args[0]);
//
Method methods[] = classType.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
{
System.out.println(methods[i].toString());
}
}
}
ReflectTester 클래스 의 copy(Object object)방법 은 다음 절 차 를 순서대로 수행 합 니 다.
(1)획득 대상 의 유형:
Class classType=object.getClass();
System.out.println("Class:"+classType.getName());
자바.lang.Object 클래스 에서 getClass()방법 을 정 의 했 기 때문에 임의의 자바 대상 에 대해 서 는 이 방법 을 통 해 대상 의 유형 을 얻 을 수 있 습 니 다.Class 클래스 는 Reflection API 의 핵심 클래스 입 니 다.getName():클래스 의 전체 이름 을 얻 는 방법 이 있 습 니 다.
getFields():클래스 의 Public 형식의 속성 을 얻 습 니 다.
getDeclared Fields():클래스 의 모든 속성 을 획득 합 니 다.
getMethods():클래스 의 Public 형식 을 얻 는 방법 입 니 다.
getDeclared Methods():클래스 를 얻 는 모든 방법.
getMethod(String name,Class[]parameterTypes):클래스 를 얻 는 특정한 방법,getMethod(String name,Class[] parameterTypes):클래스 의 특정한 방법,name 매개 변수 지정 방법의 이름,parameterTypes 매개 변수 지정 방법의 매개 변수 유형 을 얻 습 니 다.
getConstructors():클래스 의 Public 유형의 구조 방법 을 얻 습 니 다.
getConstructor(Class[]parameterTypes):클래스 의 특정 구조 방법 을 얻 고 parameterTypes 매개 변 수 는 구조 방법의 매개 변수 유형 을 지정 합 니 다.
new Instance():클래스 의 매개 변수 가 없 는 구조 방법 으로 이러한 대상 을 만 듭 니 다.
(2)기본 구조 방법 으로 새 대상 만 들 기:
Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
상기 코드 는 먼저 Class 류 의 getConstructor()방법 을 호출 하여 Constructor 대상 을 얻 었 습 니 다.이것 은 기본 적 인 구조 방법 을 대표 한 다음 에 호출 합 니 다. Constructor 대상 의 new Instance()방법 은 인 스 턴 스 를 구성 합 니 다.
(3)획득 대상 의 모든 속성:
Field fields[]=classType.getDeclaredFields();
Class 클래스 의 getDeclared Fields()방법 은 클래스 의 모든 속성 을 되 돌려 줍 니 다.Public,proctected,기본 값 과 private 접근 등급 의 속성 을 포함 합 니 다.
(4)각 속성 에 해당 하 는 getXXX()와 setXXX()방법 을 획득 한 후 이 방법 을 실행 하여 원래 대상 의 속성 을 새로운 대상 에 복사 합 니 다.
예 코드 는 다음 과 같 습 니 다.
public class ReflectTester
{
public Object copy(Object object) throws Exception
{
//
Class<?> classType = object.getClass();
System.out.println("Class:" + classType.getName());
//
Object objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});
//
Field fields[] = classType.getDeclaredFields();
for (int i = 0; i < fields.length; i++)
{
Field field = fields[i];
String 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()
Method getMethod = classType.getMethod(getMethodName, new Class[] {});
// setXXX()
Method setMethod = classType.getMethod(setMethodName, new Class[] { field.getType() });
// getXXX()
Object value = getMethod.invoke(object, new Object[] {});
System.out.println(fieldName + ":" + value);
// setXXX()
setMethod.invoke(objectCopy, new Object[] { value });
}
return objectCopy;
}
public static void main(String[] args) throws Exception
{
Customer customer = new Customer("Tom", 21);
customer.setId(new Long(1));
Customer customerCopy = (Customer) new ReflectTester().copy(customer);
System.out.println("Copy information:" + customerCopy.getId() + " " + customerCopy.getName() + " "
+ customerCopy.getAge());
}
}
class Customer
{
private Long id;
private String name;
private int age;
public Customer()
{
}
public Customer(String name, int age)
{
this.name = name;
this.age = age;
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
반사 체 제 를 이용 하여 InvokeTester 대상 의 add()와 echo()방법 을 호출 합 니 다.
예 3:
public class InvokeTester
{
public int add(int param1, int param2)
{
return param1 + param2;
}
public String echo(String msg)
{
return "echo: " + msg;
}
public static void main(String[] args) throws Exception
{
Class<?> classType = InvokeTester.class;
Object invokeTester = classType.newInstance();
// Object invokeTester = classType.getConstructor(new
// Class[]{}).newInstance(new Object[]{});
// InvokeTester add()
Method addMethod = classType.getMethod("add", new Class[] { int.class, int.class });
Object result = addMethod.invoke(invokeTester, new Object[] { new Integer(100), new Integer(200) });
System.out.println((Integer) result);
// InvokeTester echo()
Method echoMethod = classType.getMethod("echo", new Class[] { String.class });
result = echoMethod.invoke(invokeTester, new Object[] { "Hello" });
System.out.println((String) result);
}
}
add()방법의 두 매개 변 수 는 int 형식 입 니 다.add()방법 을 나타 내 는 Method 대상 의 코드 는 다음 과 같 습 니 다.
Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});
Method 류 의 invoke(Object obj,Object args[])방법 으로 받 은 매개 변 수 는 대상 이 어야 하 며,매개 변수 가 기본 형식 데이터 라면 해당 포장 유형의 대상 으로 변환 해 야 합 니 다.invoke()방법의 반환 값 은 항상 대상 입 니 다.실제 호출 된 방법의 반환 유형 이 기본 형식 데이터 라면 invoke()방법 은 해당 포장 유형의 대상 으로 변환 한 다음 되 돌려 줍 니 다.
이 예 에서 InvokeTester 류 의 add()방법의 두 가지 매개 변수 와 반환 값 은 모두 int 형식 임 에 도 불구 하고 add Method 대상 의 invoke()방법 을 호출 할 때 Integer 형식의 매개 변수 만 전달 할 수 있 고 invoke()방법의 반환 유형 도 Integer 유형 이 며 Integer 류 는 int 기본 유형의 포장 류 입 니 다.
Object result=addMethod.invoke(invokeTester,
new Object[]{new Integer(100),new Integer(200)});
System.out.println((Integer)result); //result 는 Integer 형식 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.