Search
Duplicate
📒

[Java Study] 03. Class, 리플렉션과 어노테이션

상태
완료
수업
Java Study
주제
연관 노트
3 more properties
참고

java.lang.Class - reflect

NOTE
자바의 Class 클래스는 클래스의 정보(메타 데이터)를 다루는 리플렉션의 기반이며, 런타임에 클래스의 메타데이터에 접근하고 조작할 수 있습니다. 이를 통해 동적으로 객체를 생성하고 메서드를 호출하는 고급 기능을 제공합니다.
public static void main(String[] args) throws Exception{ // 클래스 불러오기 Class clazz = String.class; Class clazz1 = new String().getClass(); Class<?> clazz2 = Class.forName("java.lang.String"); // 생성자 정보 얻기 Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("constructor = " + constructor); Class[] parameterTypes = constructor.getParameterTypes(); for (Class parameterType : parameterTypes) { System.out.println("parameterType = " + parameterType); } } // 필드 정보 얻기 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("field = " + field.getType() + " " + field.getName()); } // 메서드 정보 얻기(전체 혹은 하나를 가져올 수 있다.) Method[] declaredMethods = clazz.getDeclaredMethods(); Method declaredMethod = clazz.getDeclaredMethod("toString"); for (Method method : declaredMethods) { System.out.println("method = " + method); Parameter[] parameters = method.getParameters(); for (Parameter parameter : parameters) { System.out.println("parameter = " + parameter); } } System.out.println("declaredMethod = " + declaredMethod); // 슈퍼 클래스 정보 얻기 System.out.println("SuperClass " + clazz.getSuperclass().getName()); // 구현 인터페이스 정보 얻기 Class[] interfaces = clazz.getInterfaces(); for (Class i : interfaces) { System.out.println("i = " + i); } }
Java
복사
class 예제코드(더 많은 메서드들이 있다.)
타입 정보 얻기: 클래스의 이름, 슈퍼 클래스, 인터페이스, 접근 제한자 등과 같은 정보를 조회할 수 있습니다.
리플렉션: 클래스에 정의된 메서드 필드, 생성자 등을 조회하고, 이들을 통해 객체 인스턴스를 생성하거나 메서드를 호출하는 등의 작업을 할 수 있습니다.
동적 로딩과 생성: Class.forName() 메서드를 사용해 클래스를 동적으로 로드하고, newInstance()메서드를 통해 생성할 수 있습니다.
애노테이션 처리: 클래스에 적용된 애노테이션을 조회하고 처리하는 기능을 제공합니다.

Class 리플렉션

NOTE
Class 클래스에는 클래스의 모든 정보가 들어 있습니다. 이 정보를 기반으로 인스턴스를 생성하거나, 메서드를 호출하고, 필드의 값을 변경할 수 있습니다.
public class Hello { public String message = "hello"; public String hello(){ return message; } }
Java
복사
예제 클래스
public static void main(String[] args) throws Exception{ // 클래스 정보를 가져온다. Class helloClass = Hello.class; Class helloClass2 = Class.forName("lang.clazz.Hello"); // Hello 클래스의 인스턴스 생성 Hello hello = (Hello) helloClass.getDeclaredConstructor().newInstance(); // hello 메서드 호출 String result = hello.hello(); System.out.println("result = " + result); Field message = helloClass.getDeclaredField("message"); // 필드 접근 message.setAccessible(true); // private 필드 접근 가능하게 설정 message.set(hello, "Hello, Reflection!"); // 변경된 필드 값을 사용하여 메서드 호출 String updatedResult = hello.hello(); System.out.println("updatedResult = " + updatedResult); // 동적으로 메서드 호출하기 Method helloMethod = helloClass.getDeclaredMethod("hello"); String dynamicResult = (String) helloMethod.invoke(hello); System.out.println("dynamicResult = " + dynamicResult); }
Java
복사
리플렉션 예제

어노테이션

NOTE
자바 어노테이션은 코드에 메타데이터를 추가하는 방법을 제공합니다. 이는 코드 작성 방식, 컴파일/런타임 시 처리 정보, 그리고 리플렉션을 통해 사용 가능한 구성 데이터를 제공합니다.
// 메소드가 슈퍼클래스의 메소드를 오버라이드한다는 것을 나타냅니다. @Override // 메소드나 클래스가 더 이상 사용되지 않으멀로 사용을 지양해야 한다는 것을 나타냅니다. @Deprecated // 컴파일러 경고를 무시하도록 지시합니다. @SuppressWarnings // 제네릭 타입의 가변 인자 메소드에 대한 경고를 무시하도록 지시합니다. @SafeVarargs // 인터페이스가 함수형 인터페이스임을 나타냅니다. @FunctionalInterface
Java
복사
표준 어노테이션
컴파일러에 대한 지시어: 특정 경고를 무시하도록 지시하는 등 컴파일러에 대한 정보를 제공합니다.
컴파일 시간 및 배포시간 처리: 소스 코드를 자동으로 생성하거나 XML 파일을 자동으로 생성하는 작업을 수행합니다.
런타임 처리: 실행 시간에 어노테이션을 사용하여 특정 동작을 구성하거나 실행합니다.

메타 어노테이션

NOTE
메타 어노테이션은 사용자 정의 어노테이션을 생성할 때 사용되는 어노테이션입니다. 주로 어노테이션의 동작을 정의하는데 사용됩니다.
// 어노테이션이 적용될 수 있는 요소(메소드, 필드) @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER, }) // 어노테이션의 정보가 어느 시점까지 유효한지(소스, 클래스, 런타임) @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.RUNTIME) // 어노테이션 정보가 문서에 포함될지 @Documented // 어노테이션이 자식 클래스에 상속 가능한지 @Inherited // 같은 어노테이션을 한 요소에 여러 번 적용할 수 있도록 한다. @Repeatable
Java
복사
메타 어노테이션 예제
// 마커 어노테이션 - 인자값 없음 @Retention(RetentionPolicy.RUNTIME) public @interface MyMarkerAnnotation {} // 일반 어노테이션 - 인자값 있음 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Task { String description() default "No description"; // 작업 설명 int priority() default 0; // 작업 우선순위 }
Java
복사
사용자 정의 어노테이션 예제
사용자 정의 어노테이션은 @interface로 생성할 수 있습니다.

리플렉션과 어노테이션의 조합

NOTE
리플렉션어노테이션을 조합해서 런타임에 클래스, 메소드, 필드 등의 정보를 조사하고 수정할 수 있는 기능을 제공할 수 있습니다.
// 사용자 정의 어노테이션 정의 @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String description(); }
Java
복사
사용자 정의 어노테이션
public class MyApplication { // 어노테이션 적용 @MyAnnotation(description = "This method adds two numbers") public int add(int a, int b) { return a + b; } public static void main(String[] args) throws Exception { // 메소드 검색 Method method = MyApplication.class.getMethod("add", int.class, int.class); // 어노테이션 적용여부 if (method.isAnnotationPresent(MyAnnotation.class)) { MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); System.out.println("Description: " + annotation.description()); int result = (Integer) method.invoke(new MyApplication(), 5, 3); System.out.println("Result: " + result); } } }
Java
복사
@MyAnnotation 리플렉션 예제