java1.1 Reflection!

리플렉션

리플렉션이란 Class클래스를 정보를 얻어와 분석, 사용하는 것.

먼저 Class클래스를 사용해서 클래스 정보를 얻어오는걸 알아보자.

import java.lang.reflect.*

Class 객체정보 얻는 방법1 - ObjectgetClass()

Class carInfo = myCar.getClass();
System.out.println(carInfo.getName());
System.out.println(carInfo.getPackage().getName());

출력

days22.Car
days22

carInfo.getPackage()를 통해 해당 클래스가 속한 패키지정보를 얻을 수 있음.

방법1은 Car객체를 인스턴스화 해야 ObjectgetClass()메서드를 통해 클래스 정보를 얻을 수 있다.

Class 객체정보 얻는 방법2 - Class.forName

String className = "com.demo.Car";
Class carInfo2 = Class.forName(className);
Car myCar2 = (Car)carInfo2.newInstance();
// public T newInstance() throws InstantiationException, IllegalAccessException

클래스 full Name(문자열)으로 클래스 정보를 얻을 수 있다.
이렇게 얻는 클래스 정보를 가지고 객체를 인스턴스화 할 수 있다.

Class 클래스로 정보를 얻어 인스턴스 생성하는것을 동적 객체생성이라 한다.

newInstance 는 제너릭 클래스를 반환하는데 DownCasting 해서 객체에 참조시킨다.

동적으로 객체생성은 java jdbc db연동 객체를 만들때 많이 사용한다. 메모리에 올라갈 jdbc드라이버를 Class.forName으로 생성한다.

객체의 생성자 정보 얻어내기 - ClassgetConstructors() 메서드 사용

getConstructors() 원형

public Constructor<?>[] getDeclaredConstructors() throws SecurityException

Constructor 클래스 원형

public final class Constructor<T> extends Executable

일단 getConstructors() 메서드를 호출하면 생성자 정보들이 든 객체배열 Constructor[]를 반환한다.

Constructor[] cs = carInfo.getDeclaredConstructors();

Executable 추상클래스에서 get... 시작하는 메서드들을 구현하고 있음.

for (Constructor c : cs) {
    System.out.print(Modifier.toString(c.getModifiers()));
    System.out.print(" " + carInfo.getName() + "(");
    Class[] ps = c.getParameterTypes();
    for (int i = 0; i < ps.length; i++) {
        System.out.print(ps[i].getName() + ", ");
    }
    System.out.println(")");
}
// public com.demo.Car()
// public com.demo.Car(java.lang.String, java.lang.String, java.lang.String, int, )

Constructor객체의 getModifiers - 생성자의 접근제어자, 기타제어자 정보를 정수형태로 반환
Constructor객체의 getParameterTypes - 생성자 매개변수 타입을 Class객체 배열로 반환

객체의 필드정보 얻어내기 - ClassgetDeclaredFields()메서드 사용

getDeclaredFields() 메서드 원형

public Field[] getDeclaredFields() throws SecurityException

Field 클래스 원형

public final class Field extends AccessibleObject implements Member

일단 Class객체의 getDeclaredFields() 메서드를 호출하면 필드정보가 든 Field배열 반환

Field[] fs = carInfo.getDeclaredFields();

Member인터페이스에 get... 추상 메서드가 선언되있고
Field에서 이를 오버라이딩해서 사용중.

for (Field f : fs) {
    System.out.print(Modifier.toString(f.getModifiers()));
    System.out.println(" " + f.getType().getName() + " " + f.getName());
}
// public staticjava.lang.String name
// public staticjava.lang.String gearType
// public staticjava.lang.String color
// int speed

Constructor클래스의 getModifiers()메서드 처럼 FieldgetModifiers()메서드도 접근제어자 기타제어자 정보를 정수로 반환.

FieldgetType()메서르도 멤버필드 typde명을, getName으로 멤버필드 이름을 반환.

객체의 메서드 정보 얻어내기 - ClassgetDeclaredMethods()메서드 사용

getDeclaredMethods 원형

public Method[] getDeclaredMethods() throws SecurityException

Method클래스 원형

public final class Method extends Executable

일단 ClassgetDeclaredMethods()메서드 를 호출해서 메서드 정보가든 Method배열을 반환

Method[] ms = carInfo.getDeclaredMethods();

Constructor 클래스랑 비슷한 형식
public final class Constructor<T> extends Executable

for (Method m : ms) {
    Class[] ps = m.getParameterTypes(); //매개변수 배열로 저장
    System.out.print(Modifier.toString(m.getModifiers()));
    System.out.print(" " + m.getReturnType() + " " + m.getName() + "("); //반환형 + 이름
    for (int i = 0; i < ps.length; i++) {
        System.out.print(ps[i].getName() + ","); //매개변수 출력
    }
    System.out.println(")");
}
// public void speedDown(int,java.lang.String,)
// public void speedUp(int,java.lang.String,)
// public void Stop(boolean,)

MethodgetParameterTpyes()메서드로 매개변수 type이든 Class배열을 반환.

Class객체로 받은 정보로 분석하는것이 리플렉션이라는걸 알아두자.

리플렉션을 통해 수많은 Java 라이브러리들이 개발되었으며 Spring 프레임워크또한 그중 하나이다.

isAssignableFrom

  • instanceof 특정 Object가 어떤 클래스/인터페이스를 상속/구현했는지를 체크
  • Class.isAssignableFrom() 특정 Class가 어떤 클래스/인터페이스를 상속/구현했는지 체크합니다.

카테고리:

업데이트: