티스토리 뷰

우선 Constructor 클래스중에 getConstructor 혹은 getDeclaredConstructor 메소드를 호출할 때 발생하는 예외인 NoSuchMethodException 을 알아보자. 아래와 같이 프로젝트 하나 만들고 패키지도 2개 만들어 주자.




첫번째로 com.reflection.target 패키지 안에 TargetClass2 클래스를 만들자.


[TargetClass2.java]

package com.reflection.target;

public class TargetClass2 {
	
	private String str;
	
	public TargetClass2(String str){
		this.str = str;
	}

}



두번째로 Constructor 객체를 구할 테스트 클래스를 만들자. 앞에 만든 클래스를 가지고 테스트하게 된다.

com.reflection.sample 패키지 안에다 ConstructorSample 클래스를 만들자.


[ConstructorSample.java]

package com.reflection.sample;

import java.lang.reflect.Constructor;

public class ConstructorSample {
	
	public void execute(){
		
		Class clazz = null;
		
		try {
			clazz = Class.forName("com.reflection.target.TargetClass2");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Constructor constructor = null;
        Class[] constructorParameterTypes = {String.class};
        
		try {
			constructor = clazz.getConstructor(constructorParameterTypes);
			System.out.println("생성자 찾기 성공");
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args){
		new ConstructorSample().execute();
	}
	
}

TargetClass2 클래스에 있는 생성자 중에 String 객체를 하나만 받는 생성자를 찾는 내용이다.

실행하면 알겠지만, 예외없이 "생성자 찾기 성공" 메시지가 출력되면서 프로그램이 정상 종료된다.


자 에러를 내보자. ConstructorSample.java 파일의 19라인을 아래와 같이 수정하자.

Class[] constructorParameterTypes = {Integer.class};

Integer 객체를 받는 생성자는 TargetClass2 클래스 안에 없으므로 당연히 NoSuchMethodException 예외가 발생한다.


java.lang.NoSuchMethodException: com.reflection.target.TargetClass2.<init>(java.lang.Integer)
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getConstructor(Unknown Source)
    at com.reflection.sample.ConstructorSample.execute(ConstructorSample.java:22)
    at com.reflection.sample.ConstructorSample.main(ConstructorSample.java:33)




자 이제 getConstructor 와 getDeclaredConstructor 메소드들의 차이를 알아보자.

TargetClass2 의 생성자를 private 으로 바꿔보자.

package com.reflection.target;

public class TargetClass2 {
	
	private String str;
	
	private TargetClass2(String str){  // 생성자의 접근자를 private 로 바꾸자.
		this.str = str;
	}

}

ConstructorSample.java 파일의 19라인을 아래같이 원래대로 String.class 로 올바르게 바꾼다.

Class[] constructorParameterTypes = {String.class};


실행해보면 알겠지만 똑같이 NoSuchMethodException 예외가 발생한다. 이와같이 getConstructor 메소드는 public 접근자를 가진 생성자만 인식하기때문에 이걸로는 우리가 private 로 바꾼 생성자에 접근할 수가 없다. 하지만 무조건 안되는 건 아니다. 바로 getDeclaredConstructor 메소드를 사용하면된다.


ConstructorSample.java 파일의 22라인을

constructor = clazz.getDeclaredConstructor(constructorParameterTypes);

로 바꿔서 실행해보자. 실행결과, 예외가 발생하지 않는다. 즉 getDeclaredConstructor 메소드는 public, protected, private, default 상관없이 class 안의 모든 생성자에 접근 가능하다.







반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함