2021-02-02
자바의 새로운 객체를 생성하기 위해 new라는 연사자를 많이 사용했을 것이다. 하지만 다른 방법이 또 하나 있는데 바로 newInstance를 사용하는 것이다. 이는 초기 코드 작성 시 클래스의 이름을 결정할 수 없고 프로그램이 동작하는 시점에 이름이 결정하는 경우에 사용하게 된다.
예제 코드로 사용자의 정보를 나타낼 인터페이스 한개와 각 정보를 출력하는 구현 클래스 2개를 코드로 작성하였다.
※ 인터페이스
package NewInstance;
public interface Info {
public void myInfo();
}
※ 구현클래스(신체정보)
package NewInstance;
public class BodyInfo implements Info{
@Override
public void myInfo() {
System.out.println("나의 키는 200cm");
System.out.println("나의 몸무게는 100kg");
}
}
※ 구현 클래스(인적정보)
package NewInstance;
public class PersonalInfo implements Info{
@Override
public void myInfo() {
System.out.println("나의 이름은 aaa");
System.out.println("나의 나이는 25세");
}
}
이제 실행 클래스로 가 newInstance를 사용해보자. 아래는 해당 실행 코드이다.
package NewInstance;
public class main {
public static void main(String[] args) {
try {
Class clazz1 = Class.forName("NewInstance.BodyInfo");
Info info =(Info) clazz1.newInstance();
//리턴값이 Object이기 때문에 Info로 한 번 감싸준다.
info.myInfo();
}catch(Exception e){
e.printStackTrace();
}
try {
Class clazz2 = Class.forName("NewInstance.PersonalInfo");
Info info =(Info) clazz2.newInstance();
//리턴값이 Object이기 때문에 Info로 한 번 감싸준다.
info.myInfo();
}catch(Exception e){
e.printStackTrace();
}
//예외의 경우 ClassNotFoundException / InstantiationException / IllegalAccessException 들이 발생할 수 있음
//근데 한번에 처리하기 위해서 그냥 Exception을 넣음
}
}
위의 코드와 같이 우선 Class.forName으로 구현 클래스를 클래스 객체로 받는다. 다음에 인터페이스로 해당 구현 클래스 객체를 newInstance로 받아서 인터페이스 객체로 해당 구현 클래스의 메서드를 사용하는 것이다. 표현이 조금 어려울 수 있으나, 요약하자면 만들어진 Class 객체의 매개변수가 기존의 Info의 구현 클래스이기만 하면, 인터페이스 객체 변수로 구현 클래스의 오버 라이딩된 메서드를 사용할 수 있다는 것이다. 코드를 실행시켜보면 아래와 같이 결과를 얻을 수 있다.
결과를 보면 단순 인터페이스 객체임에도 불구하고 구현 클래스의 재정의된 메서드를 사용할 수 있다.
(다만 newInstance의 경우 9 버전 이후로 deprecated(비추천) 되어 현재는 잘 사용하지는 않는다.)
사실 new 연산자로 바로 구현 클래스를 받아도 그 결과는 같다.
package NewInstance;
public class Main2 {
public static void main(String[] args) {
Info info1 = new BodyInfo();
Info info2 = new PersonalInfo();
info1.myInfo();
info2.myInfo();
}
}