[Java] Class 클래스
Class 클래스
자바는 클래스와 인터페이스의 메타 데이터를 java.lang.Class
의 클래스를 통해 관리한다. 메타 데이터란 클래스 이름, 필드, 생성자, 메서드 등을 말한다.
Class 객체 얻기
Object
의 getClass()
를 통해 얻을 수 있다. 해당 메서드는 인스턴스를 생성했을 때만 사용할 수 있다. 인스턴스를 통하지 않고 Class
의 정적 메서드인 forName()
을 통해 직접 클래스를 얻어오는 방법도 있다. 이 때 forName()
의 인자로는 패키지가 포함된 클래스 또는 인터페이스 이름을 넣어주어야 한다.
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
String
으로 된 클래스 또는 인터페이스를 찾아 내부적으로 Reflection
을 이용하고 있는 걸 알 수 있다.
아래는 간단한 예제이다. 해당 메서드를 이용할 때 인자로 대입된 값으로 클래스를 찾지 못하면 ClassNotFoundException
을 발생시키므로 예외처리를 적절히 해주어야 한다.
public class ClassExam {
public static void main(String[] args) throws ClassNotFoundException {
Author author = new Author();
Class authorClass = author.getClass(); // 인스턴스 생성하여 Class 객체 얻어오기
Class clazz = Class.forName("org.java.chap11.apis.clone.Author"); // forName()으로 Class 객체 얻어오기
System.out.println(clazz.getName());
System.out.println(Arrays.toString(clazz.getDeclaredMethods()));
System.out.println(Arrays.toString(clazz.getClasses()));
}
}
org.java.chap11.apis.clone.Author
[public java.lang.String org.java.chap11.apis.clone.Author.toString(), protected java.lang.Object org.java.chap11.apis.clone.Author.clone() throws java.lang.CloneNotSupportedException, public java.lang.String org.java.chap11.apis.clone.Author.getName(), public java.lang.String org.java.chap11.apis.clone.Author.getId(), public void org.java.chap11.apis.clone.Author.setName(java.lang.String), public java.lang.String org.java.chap11.apis.clone.Author.getCountry(), public org.java.chap11.apis.clone.Biography org.java.chap11.apis.clone.Author.getBiography(), public void org.java.chap11.apis.clone.Author.setCountry(java.lang.String), public java.lang.String org.java.chap11.apis.clone.Author.getAge(), public void org.java.chap11.apis.clone.Author.setBooks(java.lang.String[]), public org.java.chap11.apis.clone.Author org.java.chap11.apis.clone.Author.cloneAuthor(), public void org.java.chap11.apis.clone.Author.setBiography(org.java.chap11.apis.clone.Biography), public void org.java.chap11.apis.clone.Author.setId(java.lang.String), public java.lang.String[] org.java.chap11.apis.clone.Author.getBooks(), public void org.java.chap11.apis.clone.Author.setAge(java.lang.String)]
위와 같은 두 가지 방식으로 클래스를 찾아올 수 있다. 패키지까지 모두 검색하는 것은 복잡할 수 있으므로 인스턴스를 통해 Class 객체를 얻어오는 것이 편해보인다.
Reflection
위와 같이 클래스나 인터페이스의 메타 정보를 찾아내는 것을 리플렉션이라고 한다. 위 예시에서 사용한 메서드 말고 다양한 메서드를 통해 클래스의 정보를 알아낼 수 있다.
예를 들어 getDeclaredMethods()
는 클래스 내부에 선언된 생성자의 정보를 배열의 형태로 받아온다. 상속받은 생성자는 무시하는데, 상속된 내용까지 확인하고 싶다면 getMethods()
를 이용하면 된다.
동적 객체 생성
Class
클래스의 newInstance()
를 활용하면 런타임 시에 지정해둔 클래스를 동적으로 객체를 생성할 수도 있다.
newInstance()
는 두 가지 예외를 발생시킨다. 따라서 예외 처리를 해주어야 한다.
InstantiationException
:
대입된 클래스가 추상 클래스이거나 인터페이스여서 인스턴스화할 수 없는 경우
IllegalAccessException
:
클래스나 생성자가 접근제한자로 인해 접근할 수 없을 경우
newInstance()
리턴 타입은 Object
이므로 생성한 인스턴스를 변수에 저장하기 위해서는 변수 타입에 맞게 캐스팅을 해주어야 한다. 그런데 컴파일 단계에서는 어떤 타입의 변수를 쓸지 알 수가 없으므로 인터페이스를 구현하여 처리한다(구현 클래스의 형태는 인터페이스만 구현하면 형을 다양하게 바꿀 수 있으므로). 아래의 예시를 보자.
public interface TestInterface {
void method1();
}
public class RuntimeClass1 implements TestInterface{
@Override
public void method1() {
System.out.println("runtime class 1");
}
}
public class RuntimeClass2 implements TestInterface {
@Override
public void method1() {
System.out.println("RuntimeClass 2");
}
}
public class NewInstanceExam {
public static void main(String[] args) {
try {
Class clazz = Class.forName("org.java.chap11.apis.clazz.RuntimeClass1");
TestInterface testInterface = (TestInterface) clazz.newInstance();
testInterface.method1();
} catch (ClassNotFoundException | InstantiationException |IllegalAccessException e ){
e.printStackTrace();
}
}
}
runtime class 1
위와 같이 동적으로 생성할 인스턴스를 forName()
으로 얻어온 뒤 TestInterface
타입으로 캐스팅해주면 인터페이스를 구현하는 인스턴스를 생성할 수 있다.
source: github
reference: 「이것이 자바다」, 신용권
Author And Source
이 문제에 관하여([Java] Class 클래스), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hsbang_thom/Java-Class-클래스저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)