java1.1 Reflection!
리플렉션
리플렉션이란 Class
클래스를 정보를 얻어와 분석, 사용하는 것.
먼저 Class
클래스를 사용해서 클래스 정보를 얻어오는걸 알아보자.
import java.lang.reflect.*
Class 객체정보 얻는 방법1 - Object
의 getClass()
Class carInfo = myCar.getClass();
System.out.println(carInfo.getName());
System.out.println(carInfo.getPackage().getName());
출력
days22.Car
days22
carInfo.getPackage()
를 통해 해당 클래스가 속한 패키지정보를 얻을 수 있음.
방법1은 Car
객체를 인스턴스화 해야 Object
의 getClass()
메서드를 통해 클래스 정보를 얻을 수 있다.
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
으로 생성한다.
객체의 생성자 정보 얻어내기 - Class
의 getConstructors()
메서드 사용
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
객체 배열로 반환
객체의 필드정보 얻어내기 - Class
의 getDeclaredFields()
메서드 사용
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()
메서드 처럼 Field
의 getModifiers()
메서드도 접근제어자 기타제어자 정보를 정수로 반환.
Field
의 getType()
메서르도 멤버필드 typde
명을, getName
으로 멤버필드 이름을 반환.
객체의 메서드 정보 얻어내기 - Class
의 getDeclaredMethods()
메서드 사용
getDeclaredMethods
원형
public Method[] getDeclaredMethods() throws SecurityException
Method
클래스 원형
public final class Method extends Executable
일단 Class
의 getDeclaredMethods()
메서드 를 호출해서 메서드 정보가든 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,)
Method
의 getParameterTpyes()
메서드로 매개변수 type
이든 Class
배열을 반환.
Class
객체로 받은 정보로 분석하는것이 리플렉션이라는걸 알아두자.
리플렉션을 통해 수많은 Java 라이브러리들이 개발되었으며 Spring 프레임워크또한 그중 하나이다.
isAssignableFrom
instanceof
특정 Object가 어떤 클래스/인터페이스를 상속/구현했는지를 체크Class.isAssignableFrom()
특정 Class가 어떤 클래스/인터페이스를 상속/구현했는지 체크합니다.