THE SYS4U DODUMENT Java Reflection & Introspection 2012.08.21 김진아사원 2012 SYS4U I&C All rights reserved.
목차 I. 개념 1. Reflection 이란? 2. Introspection 이란? 3. Reflection 과 Introspection 의차이점 II. 실제사용예 1. Instance의생성 2. Class Type 생성 3. Instanceof 대체 Reflection API 4. Class의생성자의정보얻기 5. Class의 Field 얻기 6. Class의 Method 얻기 7. Method 의이름으로 Method 실행하기 8. Field값변경 9. 배열에서의사용 10. Reflection 을이용한 Factory pattern Ⅲ. 관련라이브러리 Ⅳ. Q&A 1. Commons.BeanUtils THE SYS4U PAPER 2012 2
I. 개념 THE SYS4U PAPER 2012 3
I. Reflection 이란? Ⅰ. 개념 Java.lang.reflect 패키지사용 클래스인스턴스로부터그인스턴스가표현하는멤버, 필드, 메소드에접근할수있는기능 클래스구조에대한정보뿐만아니라객체의생성, 메소드호출, 필드접근까지가능 THE SYS4U PAPER 2012 4
Ⅱ. Introspection 이란? Ⅰ. 개념 빈의프로퍼티와메소드등을알려주기위해빈의디자인패턴을자동으로분석하는과정 객체의클래스, 구현메소드, 필드등의객체정보를조사하는과정을의미 THE SYS4U PAPER 2012 5
Ⅲ. Reflection 과 Introspection 의차이점 Ⅰ. 개념 Reflection 조작 Introspection 조사 THE SYS4U PAPER 2012 6
Ⅱ. 실제사용예 THE SYS4U PAPER 2012 7
Ⅰ. Instance 의생성 (1/3) new Ⅱ. 실제사용예 public class Sample { private void outputmessage(){ System.out.println("outputMessage"); public static void main(string[] args) throws Exception { Sample sample1 = new Sample(); sample1.outputmessage(); 실행결과 outputmessage THE SYS4U PAPER 2012 8
Ⅰ. Instance 의생성 (2/3) clone Ⅱ. 실제사용예 public class Sample implements Cloneable{ private void outputmessage(){ System.out.println("outputMessage"); public static void main(string[] args) throws Exception { Sample sample1 = new Sample(); Sample sample3 = (Sample) sample1.clone(); sample3.outputmessage(); 실행결과 outputmessage THE SYS4U PAPER 2012 9
Ⅰ. Instance 의생성 (3/3) Class<T>.newInstance Ⅱ. 실제사용예 public class Sample { private void outputmessage(){ System.out.println("outputMessage"); public static void main(string[] args) throws Exception { Class c = Class.forName("Sample"); Sample sample2 = c.newinstance(); sample2.outputmessage(); 실행결과 outputmessage THE SYS4U PAPER 2012 10
Ⅱ. Class Type 생성 Ⅱ. 실제사용예 public static void main(string[] args) { Class c1 = Class.forName("java.lang.String"); public static void main(string[] args) { Class<Integer> c2 = int.class; public static void main(string[] args) { Class<Integer> c3 = Integer.TYPE; THE SYS4U PAPER 2012 11
Ⅲ. Instanceof 대체 Reflection API Ⅱ. 실제사용예 public class A { public static void main(string[] args) throws Exception { Class c = Class.forName("A"); boolean b1 = c.isinstance(new Integer(65)); System.out.println("new Integer(65) == > "+b1); boolean b2 = c.isinstance(new A()); System.out.println("new A() == > "+b2); 실행결과 new Integer(65) == > false new A() == > true THE SYS4U PAPER 2012 12
Ⅳ. Class 의생성자의정보얻기 Ⅱ. 실제사용예 public class Const { public Const(int i, String str){ 실행결과 public static void main(string[] args) throws Exception{ Class c= Class.forName("Const"); Constructor constlist[] = c.getdeclaredconstructors(); Class Name : class Const Constructor for (int Name i = 0; : i < Const constlist.length; i++) { ------------------------------------------------ Constructor constructor = constlist[i]; param 0 : System.out.println("Class Name : " + constructor.getdeclaringclass()); param 1 : System.out.println("Constructor class java.lang.string Name : "+ constructor.getname()); System.out.println("------------------------------------------------"); Class param[] = constructor.getparametertypes(); for (int j = 0; j < param.length; j++) { System.out.println("param "+ j +" : + param[j]); THE SYS4U PAPER 2012 13
Ⅴ. Class Field 얻기 Ⅱ. 실제사용예 public class F { private int a; public static final String b="b"; Class double : class c; F Field public Name static : a void main(string[] args) throws Exception { Field Type : int Field Modifiers : private ------------------------------------------------- Class cls = Class.forName( F"); Class : Field class fieldlist[] F = c.getdeclaredfields(); Field Name : b Field Type for (int : class i = java.lang.string 0; i < fieldlist.length; i++) { Field Modifiers : public static final ------------------------------------------------- Field field = fieldlist[i]; Class : class System.out.println("Class F : " + field.getdeclaringclass()); Field Name System.out.println("Field : c Name : " + field.getname()); Field Type System.out.println("Field : double Type : " + field.gettype()); Field Modifiers System.out.println("Field : Modifiers : " + Modifier.toString(field.getModifiers())); ------------------------------------------------- System.out.println("-------------------------------------------------"); THE SYS4U PAPER 2012 14
Ⅵ. Class 의 Method 얻기 Ⅱ. 실제사용예 public class M { private int test(string str,int i) throws NullPointerException{ if(str ==null str.equals("")) { throw new NullPointerException(); return -1; public static void main(string[] args) throws Exception { Class Class Name cls = : class Class.forName( M"); M Method Method Name methodlist[] : main = c.getdeclaredmethods(); Param 0 : class [Ljava.lang.String; for (int i = 0; i < methodlist.length; i++) { exc 0 : class java.lang.exception Method method = methodlist[i]; ReturnType System.out.println("Class : void Name : " + method.getdeclaringclass()); ------------------------------------------------ System.out.println("Method Name : "+ method.getname()); Class Name : class M Method Class Name paramlist[] : test = method.getparametertypes(); Param 0 for : class (int java.lang.string j = 0; j < paramlist.length; j++) { Param 1 : int System.out.println("Param " + j + " : " + paramlist[j]); exc 0 : class java.lang.nullpointerexception ReturnType Class exclist[]= : int method.getexceptiontypes(); ------------------------------------------------ for (int j = 0; j < exclist.length; j++) { System.out.println("exc " + j + " : " + exclist[j]); System.out.println("ReturnType : " + method.getreturntype()); System.out.println("------------------------------------------------"); THE SYS4U PAPER 2012 15
Ⅶ. Method 의이름으로 Method 실행하기 (1/2) public class A { public int add(int a, int b) { return a+b; 실행결과 Ⅱ. 실제사용예 public class B { public static void main(string[] args) throws Exception { Class c = Class.forName( A"); Class param[] = new Class[2]; param[0] = Integer.TYPE; param[1] = Integer.TYPE; Method method = c.getdeclaredmethod("add", param); 2 A a = new A(); Object arglist[] = new Object[2]; arglist[0] = new Integer(1); arglist[1] = new Integer(1); Object obj = method.invoke(a, arglist); Integer value = (Integer) obj; System.out.println(value.intValue()); THE SYS4U PAPER 2012 16
Ⅶ. Method 의이름으로 private Method 실행하기 (2/2) Ⅱ. 실제사용예 public class A { private int add(int a, int b){ return a+b; public class B { public static void main(string[] args) throws Exception { 실행결과 Class c = Class.forName( A"); Class param[] = new Class[2]; param[0] = Integer.TYPE; param[1] = Integer.TYPE; Method method = c.getdeclaredmethod("add", param); 2 A a = new A(); method.setaccessible(true); Object arglist[] = new Object[2]; arglist[0] = new Integer(1); arglist[1] = new Integer(1); Object obj = method.invoke(a, arglist); Integer value = (Integer) obj; System.out.println(value.intValue()); THE SYS4U PAPER 2012 17
Ⅷ. Field 값변경 Ⅱ. 실제사용예 public class CF { public int i; public static void main(string[] args) throws Exception { 실행결과 Class c = Class.forName( CF"); Field field = c.getfield("i"); CF cf = new CF(); System.out.println ("set 하기전 : " + cf.i); field.setint(cf, 1); System.out.println ("----------------------------------------"); System.out.println("set 한후 : " +cf.i); set 하기전 : 0 ---------------------------------------- set 한후 : 1 THE SYS4U PAPER 2012 18
Ⅸ. 배열에서의사용 Ⅱ. 실제사용예 public class CF { public static void main(string[] args) throws Exception { Class c = Class.forName("java.lang.String"); Object array = Array.newInstance(c, 10); Array.set(array, 5, "test"); String str = (String) Array.get(array, 5); System.out.println(str); 실행결과 test THE SYS4U PAPER 2012 19
Ⅹ. Reflection 을이용한 Factory pattern Ⅱ. 실제사용예 Factory Pattern 이란? public class PizzaFactory { String type = new StringBuffer(pizzaType).append(PIZZA).toString(); public class PizzaFactoryy { public static final String PIZZA="Pizza"; public Pizza getpizza(string name){ Pizza pizza=null; Class c = Class.forName(type); pizza = (Pizza) c.newinstance(); 유연한프로그래밍을위해 instance 생성을담당하는 Factory Class를두는것. public Pizza getpizzainstance(string pizzatype){ Pizza pizza=null; try { if(name.equals("cheese")){ pizza catch = new (Exception CheesePizza(); e) { throw new IllegalArgumentException( No Such Pizza [ +pizzatype+ ] ); else if(name.equals("pepperoni")){ pizza return = new pizza; PepperoniPizza(); else if(name.equals("potato")){ pizza = new PotatoPizza(); public static void main(string[] args) { return PizzaFactoryy pizza; f = new PizzaFactoryy(); Pizza pizza = f.getpizzainstance("cheese"); pizza.getpizzaname(); THE SYS4U PAPER 2012 20
Ⅲ. 관련라이브러리 THE SYS4U PAPER 2012 21
Ⅰ. Commons.BeanUtils.cloneBean (1/13) Ⅲ. 관련라이브러리 clonebean(object bean) Return Parameters 설명 Object 복제할 bean 해당빈복제 THE SYS4U PAPER 2012 22
Ⅰ. Commons.BeanUtils.cloneBean 예제 (1/13) Ⅲ. 관련라이브러리 CloneBean bean = new CloneBean(); CloneBean clone = (CloneBean) BeanUtils.cloneBean(bean); THE SYS4U PAPER 2012 23
Ⅰ. Commons.BeanUtils.copyProperties (2/13) Ⅲ. 관련라이브러리 copyproperties(object dest, Object orig) Return Parameters 설명 void 원본 bean, 대상 bean, 원본대상빈의속성과이름이모두같을경우속성값복사 THE SYS4U PAPER 2012 24
Ⅰ. Commons.BeanUtils.copyProperties 예제 (2/13) Ⅲ. 관련라이브러리 멤버필드 public int i; public String str; CopyProperties1 orig = new CopyProperties1(); orig.seti(1); orig.setstr(" 시스포유 "); System.out.println("orig bean :" + orig); CopyProperties1 dest = new CopyProperties1(); BeanUtils.copyProperties(dest, orig); System.out.println("dest bean :" + dest); 실행결과 orig bean :CopyProperties1 [i=1, str= 시스포유 ] dest bean :CopyProperties1 [i=1, str= 시스포유 ] THE SYS4U PAPER 2012 25
Ⅰ. Commons.BeanUtils.copyProperties (3/13) Ⅲ. 관련라이브러리 copyproperties(object bean, String name, Object value) Return Parameters 설명 void 원본 bean, 속성이름, 대상 bean 원본빈의해당속성값을대상빈에복사 THE SYS4U PAPER 2012 26
Ⅰ. Commons.BeanUtils.copyProperties 예제 (3/13) Ⅲ. 관련라이브러리 멤버필드 public int i; public String str; CopyProperties2 bean = new CopyProperties2(); System.out.println("copy 하기전 bean : " + bean); BeanUtils.copyProperty(bean, "str", " 시스포유 "); System.out.println("copy 한후 bean : " + bean); 실행결과 copy 하기전 bean : CopyProperties2 [i=0, str=null] copy 한후 bean : CopyProperties2 [i=0, str= 시스포유 ] THE SYS4U PAPER 2012 27
Ⅰ. Commons.BeanUtils.describe (4/13) Ⅲ. 관련라이브러리 describe(object bean) Return Parameters 설명 Map bean 해당빈의속성이름과속성값을맵으로리턴 THE SYS4U PAPER 2012 28
Ⅰ. Commons.BeanUtils.describe 예제 (4/13) Ⅲ. 관련라이브러리 멤버필드 public int i; public String str; Describe bean = new Describe(); bean.seti(1); bean.setstr(" 시스포유 "); Map<String, String> map = BeanUtils.describe(bean); System.out.println(map); 실행결과 {str= 시스포유, class=class commons_beanutils.describe, i=1 THE SYS4U PAPER 2012 29
Ⅰ. Commons.BeanUtils.getArrayProperty (5/13) Ⅲ. 관련라이브러리 getarrayproperty(object bean, String name) Return Parameters 설명 String[] Bean, 배열의속성이름 해당빈의배열속성값을리턴 THE SYS4U PAPER 2012 30
Ⅰ. Commons.BeanUtils.getArrayProperty 예제 (5/13) Ⅲ. 관련라이브러리 멤버필드 public String[] arraystr = new String[] {" 시스포유 ", " 김진아 "; GetArrayProperty bean = new GetArrayProperty(); String[] arraystr = BeanUtils.getArrayProperty(bean, "arraystr"); System.out.println("arrayStr[0] : " + arraystr[0]); System.out.println("arrayStr[1] : " + arraystr[1]); 실행결과 arraystr[0] : 시스포유 arraystr[1] : 김진아 THE SYS4U PAPER 2012 31
Ⅰ. Commons.BeanUtils.getIndexedProperty (6/13) Ⅲ. 관련라이브러리 getindexedproperty(object bean, String name) Return Parameters 설명 String Bean, 배열속성이름 빈의배열요소리턴 THE SYS4U PAPER 2012 32
Ⅰ. Commons.BeanUtils.getIndexedProperty 예제 (6/13) Ⅲ. 관련라이브러리 멤버필드 public String[] arraystr = new String[] {" 시스포유 ", " 김진아 "; GetIndexedProperty bean = new GetIndexedProperty(); String value = BeanUtils.getIndexedProperty(bean, "arraystr[0]"); System.out.println("arrayStr[0] : " + value); 실행결과 arraystr[0] : 시스포유 THE SYS4U PAPER 2012 33
Ⅰ. Commons.BeanUtils.getIndexedProperty (7/13) Ⅲ. 관련라이브러리 getindexedproperty(object bean, String name, int index) Return Parameters 설명 String Bean, 배열속성이름, 인덱스 빈의해당배열의지정된인덱스값을리턴 THE SYS4U PAPER 2012 34
Ⅰ. Commons.BeanUtils.getIndexedProperty 예제 (7/13) Ⅲ. 관련라이브러리 멤버필드 public String[] arraystr = new String[] {" 시스포유 ", " 김진아 "; GetIndexedProperty2 bean = new GetIndexedProperty2(); String value = BeanUtils.getIndexedProperty(bean, "arraystr", 1); System.out.println("arrayStr[1] : " + value); 실행결과 arraystr[1] : 김진아 THE SYS4U PAPER 2012 35
Ⅰ. Commons.BeanUtils.getMappedProperty (8/13) Ⅲ. 관련라이브러리 getmappedproperty(object bean, String name) Return Parameters 설명 String Bean, 맵속성이름 빈의해당맵의지정된인덱스값을리턴 THE SYS4U PAPER 2012 36
Ⅰ. Commons.BeanUtils.getMappedProperty 예제 (8/13) Ⅲ. 관련라이브러리 멤버필드 Public Map<String, String> map = new HashMap<String, String>(); map.put("company", " 시스포유 "); map.put("name", " 김진아 "); GetMappedProperty1 bean = new GetMappedProperty1(); String value = BeanUtils.getMappedProperty(bean, "map(company)"); System.out.println("map(company) : " + value); 실행결과 map(company) : 시스포유 THE SYS4U PAPER 2012 37
Ⅰ. Commons.BeanUtils.getMappedProperty (9/13) Ⅲ. 관련라이브러리 getmappedproperty(object bean, String name, String key) Return Parameters 설명 String Bean, 맵속성이름, 인덱스 빈의해당맵의지정된인덱스값을리턴 THE SYS4U PAPER 2012 38
Ⅰ. Commons.BeanUtils.getMappedProperty 예제 (9/13) Ⅲ. 관련라이브러리 멤버필드 Public Map<String, String> map = new HashMap<String, String>(); map.put("company", " 시스포유 "); map.put("name", " 김진아 "); GetMappedProperty2 bean = new GetMappedProperty2(); String value = BeanUtils.getMappedProperty(bean, "map", "name"); System.out.println("map(name) : " + value); 실행결과 map(name) : 김진아 THE SYS4U PAPER 2012 39
Ⅰ. Commons.BeanUtils.getNestedProperty (10/13) Ⅲ. 관련라이브러리 getnestedproperty(object bean, String name) Return Parameters 설명 String Bean, 속성이름 해당빈의중첩된속성에접근할때사용 THE SYS4U PAPER 2012 40
Ⅰ. Commons.BeanUtils.getNestedProperty 예제 (10/13) Ⅲ. 관련라이브러리 * 소스별첨 THE SYS4U PAPER 2012 41
Ⅰ. Commons.BeanUtils.getProperty (11/13) Ⅲ. 관련라이브러리 getproperty(object bean, String name) Return Parameters 설명 String Bean, 속성이름 해당빈의속성이름에해당하는값리턴 THE SYS4U PAPER 2012 42
Ⅰ. Commons.BeanUtils.getProperty 예제 (11/13) Ⅲ. 관련라이브러리 멤버필드 int i = 1; GetProperty bean = new GetProperty(); String value = BeanUtils.getProperty(bean, "i"); System.out.println("GetProperty.i : " + value); 실행결과 GetProperty.i : 1 THE SYS4U PAPER 2012 43
Ⅰ. Commons.BeanUtils.populate (12/13) Ⅲ. 관련라이브러리 populate(object bean, Map properties) Return Parameters 설명 void Bean, 속성 map 맵의지정된이름에따라해당빈의속성을채움 THE SYS4U PAPER 2012 44
Ⅰ. Commons.BeanUtils.populate 예제 (12/13) Ⅲ. 관련라이브러리 멤버필드 public String company; public String name; Map<String, String> properties = new HashMap<String, String>(); properties.put("company", " 시스포유 "); properties.put("name", " 김진아 "); Populate bean = new Populate(); System.out.println("populate 하기전 bean : " + bean); BeanUtils.populate(bean, properties); System.out.println("populate 한후 bean : " + bean); 실행결과 populate 하기전 bean : Populate [company=null, name=null ] populate 한후 bean : Populate [company= 시스포유, name= 김진아 ] THE SYS4U PAPER 2012 45
Ⅰ. Commons.BeanUtils.setProperty (13/13) Ⅲ. 관련라이브러리 setproperty(object bean, String name, Object value) Return Parameters 설명 void Bean, 속성이름, 속성이름의값 해당빈의속성값에값을설정 THE SYS4U PAPER 2012 46
Ⅰ. Commons.BeanUtils.setProperty 예제 (13/13) Ⅲ. 관련라이브러리 멤버필드 public String company; public String name; SetProperty bean = new SetProperty(); System.out.println("set 하기전 bean : "+ bean); BeanUtils.setProperty(bean, "name", " 김진아 "); System.out.println("set 한후 bean : "+ bean); 실행결과 set 하기전 bean : SetProperty [company=null, name=null ] set 한후 bean : SetProperty [company=null, name= 김진아 ] THE SYS4U PAPER 2012 47
Ⅳ. Q&A THE SYS4U PAPER 2012 48
감사합니다. THE SYS4U PAPER 2012 49