java-reflection

Java reflection and introspector.

Reflection

  1. Introduce
    Class descriptor
    Descripe features of class
    Class DOES NOT rewrite hashCode() (returns position in memory)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // Persion is a class
    // Student is a class whitch extends Persion
    public void testClass(){
    Persion p = new Persion();
    Student s = new Student();
    Class class1 = p.getClass();
    Class class2 = Persion.class;
    System.out.println(p instanceof Persion) //true
    System.out.println(p.getClass() == Persion.class) //true
    System.out.println(s instanceof Persion) //true
    System.out.println(s.getClass() == Persion.class) //false
    System.out.println(class1 == class2); // true
    System.out.println(class1.hashCode() == class2.hashCode()); // true (position in memory)
    System.out.println(class1.getName()); // full name of Persion including package path
    }
  2. Method, Field

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    // Person class
    class Person {
    private String nameļ¼›
    public void setName(String name) {
    this.name = name;
    }
    public String getName() {
    return this.name;
    }
    private void talk() {
    System.out.println("This is a private methed!");
    }
    }
    public void testNewInstance() throw Exception {
    /***Create Object Dynamically***/
    // Load class, return Class object.
    Class clazz = Class.forName("nan.javalearn.reflection.Persion");
    // Make object by Class.
    Object obj = clazz.newInstance();
    /***Method***/
    // Get `setName()` of Person
    Method m1 = clazz.getDeclareMethod("setName", String.class);
    // Call `setName()`
    m1.invoke(obj, "tom");
    // Get `getName()` of Person
    Method m2 = clazz.getDeclareMethod("getName");
    Object ret = m2.invoke(obj);
    System.out.println(ret); // tom
    // Access private method
    Method mp = clazz.getDeclareMethod("talk");
    mp.setAccessible(true); // Set accessible.
    mp.invoke(obj); // Output: This is a private method!
    // diff `getDeclareMethods()` and `getMethods()`
    Method[] ms = clazz.getMethods();
    for (Method mm : ms) {
    Systom.out.println(mm); // All methods including that extends from super class.
    }
    ms = clazz.getDeclareMethods();
    for (Method mm : ms) {
    System.out.println(mm); // Methods declared in this class.
    }
    // Get all available methods start with "get".
    ms = clazz.getMethods();
    for (Method mm : ms) {
    String fname = mm.getName();
    Class[] pytpes = mm.getParameterTypes();
    if (fname.startsWith("get") && (ptypes == null || ptypes.length == 0)) {
    int mod = mm.getModifiers(); // Get modifiers of this method.
    System.out.println(Modifer.isPublic(mod)); // If it is a public method.
    ret = mm.invoke(obj);
    System.out.println(fname + " = " + ret);
    }
    }
    /***Field***/
    Field f = clazz.getDeclareField("name");
    f.setAccessible(true);
    ret = f.get(obj);
    System.out.println(ret); // Output: tom.
    f.set(obj, "jerry"); // set `name` to `jerry`.
    }
  3. Constructor

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Person2{
    private String name;
    public Person2(String name) {
    this.name = name;
    }
    }
    public void testConstructor() throw Exception {
    Class clazz = Class.forName("nan.javalearn.reflect.Person2");
    Constructor cs = clazz.getDeclaredConstructor(String.class);
    Object obj = cs.newInstance("tom");
    System.out.println(obj);
    }
  4. Copy Properties

    • By Filed

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      public class Person3{
      private String name;
      public Person3(String name) {
      this.name = name;
      }
      }
      public void propCopy(Person3 p1, Person3 p2){
      Class clazz = p1.getClass();
      Field[] fs = clazz.getDeclareFields();
      for(Field f : fs) {
      f.setAccessible(true);
      Object ret = f.get(a);
      f.set(b, ret);
      }
      }
    • By Method
      Full code can be found in github

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      public static void copyProperty(Object a, Object b) {
      Method[] ms = a.getClass().getDeclaredMethods();
      Class bclazz = b.getClass();
      for (Method m : ms) {
      String mname = m.getName();
      Class[] paramTypes = m.getParameterTypes();
      Class retType = m.getReturnType();
      if (mname.startsWith("get")
      && (paramTypes == null || paramTypes.length == 0)
      && retType != void.class) {
      String bmname = mname.replace("get", "set");
      try {
      Method bm = bclazz.getDeclaredMethod(bmname, retType);
      Object retVal = m.invoke(a);
      bm.invoke(b, retVal);
      } catch (Exception e) {
      continue;
      }
      }
      }
      }

Other examples

  1. Proxy pattern
    full code
  2. Build object from config file
    full code