View
Reflection 이란?
왜쓰나?
기본 사용법
의 모양으로 class를 얻는다. 여기서 className은 패키지를 포함한 클래스명을 적어야한다. 이렇게 Class 객체를 얻으면 해당 클래스에 대한 annotation, field, method, constructor 등 거의 모든 정보에 접근 가능하고 해당 정보를 사용해서 인스턴스를 생성까지 할 수 있다.
사용예시
내가 받는 예상 가능 한 일정한 모양의 데이터(DB 쿼리 결과 등)를 조회해서 똑같은 모양의 클래스와 매핑하고자 할 때 사용을 하였었다. 파서도 유사한 로직을 수행할 것으로 예상된다. 만약에 어떤 api를 조회했을 때
1 2 3 4 5 | { "name" : "rura6502" "age" : 99 "country" : "korea" } |
1 2 3 4 5 | class Person { String name; int age; String country; } | cs |
위 모양의 클래스를 만들어서 매핑 시키면 활용가능한 인스턴스를 얻을 수 있을 것이다. 대충 Person 클래스의 매핑 로직을 짜면
1 2 3 4 5 6 | public Person mappingForPerson(Map<String, Object> data) { Person person = new Person(); person.name = data.get("name"); .... return person; } | cs |
위와 같은 메소드가 만들어 질 것 같은데 만약 Person 말고 다른 종류의 다양한 객체가 있으면 해당 객체의 갯수 만큼 메소드를 만들어야 된다. 하지만 여기서 reflection을 활용하면 데이터의 클래스 오브젝트를 받아서 클래스의 필드, 생성자 등 클래스에 대한 정보를 알아낸 다음에 순서에 따라서 착착 매핑시켜주고 생성자를 호출해서 만든 인스턴스를 반환하면 여러가지 클래스를 감당할 수 있는 하나의 메소드를 만들수 있게 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public <T> T mapToClassMapping(Map<String, Object> data, Class<T> mappingClass) { Set<String> keys = data.keySet(); Field[] fields = mappingClass.getDeclaredFields(); Class paramTypes[] = new Class[fields.length]; Object args[] = new Object[fields.length]; int i=0; for (String key : keys) { paramTypes[i] = fields[i].getType(); args[i] = paramTypes[i].cast(data.get(key)); i++; } Constructor<T> ct = mappingClass.getConstructor(paramTypes); return ct.newInstance(args); } | cs |
간단하게 설명하자면 매핑하고자 하는 클래스 오브젝트를 받고 생성에 필요한 필드, 필드 타입을 분석해서 Map에서 나오는 데이터와 차례차례 매핑시켜서 인스턴스를 리턴하는 메소드이다. 이 코드는 테스트용 코드로 실제로 사용하려면 약간의 고급화 과정이 필요하다. 맵의 key와 맞는 필드에 세팅한다던가 등등.. 단순히 reflection의 기능을 이해하고자 만든 코드이다. 아래는 테스트 코드.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static void main(String[] args) throws Exception { class Person { String name; Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } } Map<String, Object> testMap = new HashMap<String, Object>(); testMap.put("name", "rura6502"); testMap.put("age", 20); Person rura6502 = PrestoUtil.mapToClassMapping(testMap, Person.class); System.out.println(rura6502.name); System.out.println(rura6502.age); } | cs |
참조
'Program language > Java' 카테고리의 다른 글
디자인 패턴 cheat sheet (0) | 2022.04.10 |
---|---|
run java project with h2 without installation (0) | 2022.01.22 |