자바의 모든 모든 클래스, 인터페이스는 컴파일 후에 class 파일이 생성된다.
class 파일에는 객체의 정보(필드, 메소드, 생정자 등)가 있다.
Class 클래스는 class 파일에서 객체의 정보를 가질 수 있다.
다음과 같은 방법 Class 인스턴스를 얻을 수 있다.
// 1. 생성된 인스턴스에서 class 정보 갖고 오기
String name = new String();
Class classTest = name.getClass();
// 2. 이미 컴파일 된 클래스에서 class 정보 갖고 오기. 객체가 생성되지 않아도 가져올 수 있다.
Class classTest = String.Class;
// 3. Class의 forName() 메소드로 동적로딩 하기
Class classTest = Class.forName("java.lang.String");
보통 Class 클래스는 로컬 환경에서 존재하지 않는 클래스를 사용해야 할 경우에 많이 사용한다.
그러나 1번, 2번 방법은 이미 로컬 환경에 class 파일이 존재하는 경우이고, 컴파일할 때 클래스가 메모리에 올라간다. 이렇게 컴파일될 때, 클래스가 메모리에 올라가는 것을 정적 로딩(static loading)이라고 한다. 대부분의 클래스는 정적 로딩된다.
따라서 실제로는 로컬 환경에 얻고자 하는 클래스가 없을 때, 3번의 경우로 Class 클래스를 생성한다.
Class의 forName() 메소드는 매개 값으로 클래스의 풀네임을 넣는다. 그럼 그때 매개 값으로 넘긴 클래스가 메모리에 올라간다.
이렇게 컴파일 된 후, 프로그램이 실행 중일 때(Runtime) 필요할 때 클래스를 메모리에 올리는 것을 동적 로딩이라고 한다.
하지만 이 경우에는 없는 클래스를 가져오게 되면 (ClassNotFoundException) 예외를 발생시킬 수 있어 예외처리를 해야 한다.
3번의 방법처럼, Class 클래스로부터 객체의 정보를 가져와 프로그래밍하는 방식을 reflection 프로그래밍이라고 한다. 로컬 환경에 필요한 class가 없고, 자료형을 모를 때 유용하다.
java.lang.reflect 패키지에 있는 클래스를 활용한다.
Class가 제공하는 메소드
- forName() 메소드: 클래스의 풀네임을 매개값을 전달하면 그 클래스가 메모리에 로딩된다.
- getConstrutors() 메소드: 클래스가 갖고 있는 생성자(Constructor 타입)를 배열에 담아 리턴한다.
- getMethods() 메소드: 클래스가 갖고 있는 메소드(Method 타입)를 배열에 담아 리턴한다.
- Constructor, Method 클래스는 java.lang.reflect 패키지가 제공함
- newInstance() 메소드 : new 키워드 없이 인스턴스를 생성할 수 있다. Object 타입으로 반환하기 때문에 형변환이 필요하다. 매개 값이 없으면 기본 생성자로 생성한다.
- getConstructor() 메소드: 기본 생성자가 아닌 생성자를 가져올 수 있다. 매개 값으로 원하는 생성자의 매개 값의 Class가 담긴 배열을 전달한다. 그러면 같은 매개 값을 갖는 생성자를 반환한다.
- 이렇게 반환된 생성자에서 newInstance() 메소드를 사용해서 객체를 생성할 수 있다. getConstructor()와 비슷하게 이번에는 newInstance()의 매개 값으로 생서자에 넣을 값이 들은 Object 타입의 배열을 넣는다. 그러면 Objcet 타입으로 형변환된 인스턴스가 반환된다.
// 동적 로딩
Class classTest = Class.forName("test.Car");
// 원하는 생성자 생성. 매개값의 Class가 담긴 배열 전달.
// Consturctor 클래스는 java.lang.reflect 에서 제공
// Car(String company){} 이란 생성자를 가져오려 할 때,
Class[] parameterTypes = {String.class};
Constructor cons = classTest.getConstructor(parameterTypes);
// 생성자로 객체 생성. 매개값이 담긴 Objcet 배열 전달
Object[] initargs = {"현대자동차"};
Car car = (Car)cons.newInstance(initargs);
'study > java' 카테고리의 다른 글
자바/JAVA 람다식 (0) | 2021.03.12 |
---|---|
자바/JAVA 내부 클래스 (0) | 2021.03.12 |
자바/JAVA static, final, static final (0) | 2021.03.06 |
자바/JAVA 메모리 사용 영역(Runtime Data Area) (0) | 2021.02.23 |
자바/JAVA LIFO, FIFO 컬렉션 (0) | 2021.02.15 |