Constructor
Constructor(생성자) 제어 
이 문서에서는 Java Reflection을 이용하여 생성자 정보를 얻어내고 객체를 생성하는 방법을 다룬다.
클래스의 형태
예제에서 사용할 클래스의 형태는 다음과 같다. 다양한 생성자를 추가해두었고, 접근제한 확인을 위해 기본생성자를 private 처리해두었다.
package com.hacademy.reflection5;
public class Product {
	private String name;
	private String type;
	private int price;
	
	private Product() {
		this("미설정", "없음", 0);
	}
	public Product(String name) {
		this(name, "없음", 0);
	}
	public Product(String name, String type) {
		this(name, type, 0);
	}
	public Product(String name, String type, int price) {
		this.name = name;
		this.type = type;
		this.price = price;
	}
	
	@Override
	public String toString() {
		return "Product [name=" + name + ", type=" + type + ", price=" + price + "]";
	}
}예제 - 생성자 목록 불러오기
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
public class Test01 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		
		System.out.println("<Accessible constructor list>");
		for(Constructor<?> constructor : c.getConstructors()) {
			System.out.println(constructor);
		}
		
		System.out.println("<Declared constructor list>");
		for(Constructor<?> constructor : c.getDeclaredConstructors()) {
			System.out.println(constructor);
		}
	}
}생성자 목록을 조회할 수 있는 명령은 두 가지가 있다.
class.getConstructors()- 접근 가능한 생성자 목록을 조회class.getDeclaredConstructors()- 모든 생성자 목록을 조회
예제 - 생성자를 정하여 불러오기
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
public class Test02 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		
		//Constructor<?> c1 = c.getConstructor();//error
		Constructor<?> c2 = c.getConstructor(String.class);
		Constructor<?> c3 = c.getConstructor(String.class, String.class);
		Constructor<?> c4 = c.getConstructor(String.class, String.class, int.class);
		
		Constructor<?> c5 = c.getDeclaredConstructor();
		Constructor<?> c6 = c.getDeclaredConstructor(String.class);
		Constructor<?> c7 = c.getDeclaredConstructor(String.class, String.class);
		Constructor<?> c8 = c.getDeclaredConstructor(String.class, String.class, int.class);
		
		System.out.println("c2 = " + c2);
		System.out.println("c3 = " + c3);
		System.out.println("c4 = " + c4);
		System.out.println("c5 = " + c5);
		System.out.println("c6 = " + c6);
		System.out.println("c7 = " + c7);
		System.out.println("c8 = " + c8);
	}
}생성자를 불러올 때는 형태를 지정하여 불러온다. 다음 두 가지 명령이 존재한다.
class.getConstructor(형태)- 접근 가능한 생성자 중 형태에 맞는 생성자 객체를 반환. 없으면 NoSuchMethodException 발생class.getDeclaredConstructor(형태)- 모든 생성자 중 형태에 맞는 생성자 객체를 반환. 없으면 NoSuchMethodException 발생
예제 - 기본 생성자를 이용한 객체 생성 
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test03 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		Constructor<?> constructor = c.getDeclaredConstructor();
		constructor.setAccessible(true);
		Product product = (Product) constructor.newInstance();
		System.out.println(product);
	}
}생성자 객체에 있는 .newInstance() 메소드를 호출하면 인스턴스를 생성할 수 있다.
예제 클래스인 Product에서는 기본 생성자가 private이기 때문에 생성 전 .setAccessible(true) 설정이 필요하다.
constructor.setAccessible(true);생성 시 인스턴스가 Object 형태로 반환되므로 생성한 형태에 맞게 Down-casting 해주어야 한다.
Product product = (Product) constructor.newInstance();예제 - 매개변수 (String) 생성자 이용한 객체 생성
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test04 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		Constructor<?> constructor = c.getDeclaredConstructor(String.class);
		Product product = (Product) constructor.newInstance("컴퓨터");
		System.out.println(product);
	}
}이전 예제와 다른 점은 다음과 같다.
생성자가 접근 가능하므로
.setAccessible(true)를 사용하지 않음생성자 정보 검색 시 형태를 지정
객체 생성 시 생성자 형태에 맞는 데이터 전달
예제 - 매개변수 (String, String) 생성자 이용한 객체 생성
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test05 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		Constructor<?> constructor = c.getDeclaredConstructor(String.class, String.class);
		Product product = (Product) constructor.newInstance("컴퓨터", "전자제품");
		System.out.println(product);
	}
}예제 - 매개변수 (String, String, int) 생성자 이용한 객체 생성
package com.hacademy.reflection5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test06 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> c = Class.forName("com.hacademy.reflection5.Product");
		Constructor<?> constructor = c.getDeclaredConstructor(String.class, String.class, int.class);
		Product product = (Product) constructor.newInstance("컴퓨터", "전자제품", 1500000);
		System.out.println(product);
	}
}Last updated