안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^ |
동적 객체 생성 newInstance()
Class 객체를 이용하면 new 연산자의 사용 없이 동적으로 객체 생성이 가능합니다.
코드 작성 시에 클래스 이름을 결정할 수 없고, 런타임 시에 클래스 이름이 결정되는 경우에
매우 유용합니다.
아래 코드처럼 Class.forName() 메서드로 Class 객체를 얻음 다음 newInstance()메서드를 호출하면 Object 타입의 객체를 얻을 수 있습니다.
try{
Class clazz = Class.forName("런타임 시 결정되는 클래스의 이름");
Object obj = clazz.newInstance();
}catch(ClassNotFoundException e){
}catch(InstantiationException e){
}catch(IllegalAccessException e){
}
newInstance() 메서드는 기본 생성자를 호출해서 객체를 생성하기 때문에 반드시 클래스에 기본 생성자가 존재해야 합니다. 매개 변수가 있는 생성자를 호출하고 싶다면 리플랙션으로 Constructor 객체를
얻어 newInstance() 메서드를 호출하면 됩니다.
newInstance() 메서드는 두 가지 예외가 발생할 수 있는데,
InstantiationException예외는 해당 클래스가 추상 클래스이거나 인터페이스일 경우에 발생하고,
IllegalAccessException 예외는 클래스나 생성자가 접근 제한자로 인해 접근할 수 없을 경우에
발생합니다. 그렇기에 예외 처리가 필요합니다.
newInstance() 메서드의 리턴 타입은 Object이므로 이것을 원래 클래스 타입으로 변환해야만 메서드를 사용할 수 있습니다. 그렇게 하기 위해 강제 타입 변환을 해야하는데 클래스타입을 모르는 상태이기에 변환을 할 수가 없습니다. 이 문제를 해결하기위해서는 인터페이스의 사용이 필요합니다.
바로 사용 예제를 보겠습니다.
인터페이스
public interface Action {
public void execute();
}
구현 클래스1
public class SendAction implements Action {
@Override
public void execute() {
System.out.println("데이터를 보냅니다.");
}
}
구현 클래스2
public class ReceiveAction implements Action {
@Override
public void execute() {
System.out.println("데이터를 받습니다.");
}
}
실행 클래스
public class NewInstanceExample {
public static void main(String[] args) {
try {
Class clazz = Class.forName("패키지이름.SendAction");
//Class clazz = Class.forName("패키지이름.ReceiveAction");
//이 두줄은 번갈아가며 주석 처리해주면 아래같은 실행 결과를 얻을 수 있습니다.
Action action = (Action) clazz.newInstance();
action.execute();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
다음 포스팅부터는 String 클래스에 대해 공부하겠습니다.