22.5.12 [HackerRank]Java Reflection - Attributes

서태욱·2022년 5월 12일
0

Algorithm

목록 보기
42/45
post-thumbnail

✅ 문제 분석

자바 리플렉션은 런타임에 클래스 속성을 검사하는 도구다.
예를 들어 getDeclaredMethods()를 사용하면 클래스의
공개 필드 목록을 검색할 수 있다.

이 문제는 제공되는 solution 클래스의 미완성된 라인들을 채워서
Student 클래스의 모든 메소드를 알파벳 순서로 프린트 하도록 만들어야 한다.

코드 실행 전 Student클래스가 onlinejudge에서 자동으로 append된다.

샘플 입,출력이 없는 문제다.

🌱 배경지식

자바 리플렉션

구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API

런타임에 지금 실행되고 있는 클래스를 가져와서 실행해야하는 경우

동적으로 객체를 생성하고 메서드를 호출하는 방법이다.

자바의 리플렉션은 객체를 통해 클래스, 인터페이스, 메소드들을 찾을 수 있고, 객체를 생성하거나 변수를 변경하거나 메소드를 호출할 수 있다.

클래스 파일의 위치나 이름만 있으면, 해당 클래스의 정보를 얻어내고, 객체를 생성하는 것 또한 가능하게 해주는 유연한 프로그래밍을 위한 기법이다.

코드를 작성할 시점에는 어떤 타입의 클래스를 사용할지 모르지만, 런타임 시점에 지금 실행되고 있는 클래스를 가져와서 실행해야 하는 경우, 프레임워크나 IDE에서 이런 동적인 바인딩을 이용한 기능을 제공한다. intelliJ의 자동완성 기능, 스프링의 어노테이션이 리플렉션을 이용한 기능이다.

class Person {
    int age;

    Person() {
        this.age = 27;
    }

    Person(int age) {
        this.age = age;
    }

    int getAge() {
        return this.age;
    }
}

생성자 찾기:getDeclaredConstructor()를 이용

Class clazz = Class.forName("Person");
Constructor constructor = clazz.getDeclaredConstructor();

Method 찾기: getDeclaredMethods()를 이용

Class clazz = Person.class;
Method[] methodList = clazz.getDeclaredMethods();    
System.out.println(methods[0].invoke(clazz.newInstance())) // 27이 출력됨

cf) getMethod()와 getDeclaredMethod()의 차이

getMethod()는 public method 뿐만아니라 base class 의 상속되어 있는 
superclasses 와 superinterface 의 메서드 전부를 가져오고,
getDeclaredMethod() 는 해당 클래스에만 선언된 method 를 가져옵니다.

Field 변경: getDeclaredFields()

Class clazz = Person.class;
Field[] field = clazz.getDeclaredFields();
System.out.println(field[0]);   // 출력 : int reflection_test.Person.age

✏️ 해설

public class Solution {

        public static void main(String[] args){
            Class student = Student.class; 
            //Class.forName("패키지 전체 경로") 또는 클래스 이름.class로 해당 클래스의 정보를 담은 Class 클래스가 반환된다. 
            Method[] methods = student.getDeclaredMethods();
//getDeclaredMethods()를 이용해 Student 클래스에 있는 메소드들을 찾아준다.
            List<String> methodList = new ArrayList<>();
            // methodList라는 이름으로 ArrayList를 만들어 주고,
            for(Method m : methods){ // methods 배열 항목을 변수명 m인 컬렉션 안에서 반복문 돌리면서 methodList에 담아준다.
                methodList.add(m.getName()); // 패키지 명이 포함된 클래스 명 추출
            }
            Collections.sort(methodList);
            // sort로 알파벳 정렬. 이때, 문제에서는 Student 클래스가 감추어져 있지만 
            // sort를 사용하려면 Comparable 인터페이스를 구현해야(compareTo(T obj)메소드를 오버라이딩해야) 한다.
            for(String name: methodList){
                System.out.println(name);
            }
        }
    }

👉 참고

profile
re:START

0개의 댓글