反射
终极手段。规则破坏者
1.calss
定义类关键字
2. Construtor
构造函数的描述符
Class clazz = Person.class;
Constructor ctor = clazz.getConstructor(...);
ctor.setAccessible(true);
ctor.newInstance(...);
3. field
字段(成员变量)描述符
Field f = clazz.getDeclaredField("name");
4. method
方法描述符
静态方法也可以通过反射访问
Method m = clazz.getDeclearMethod("run");
m.invoke(null);
5. Modifier
修饰符,判断是否含有指定的修饰符
Modifier.isStatic(m.getModifier());
// Person.java
1 package com.hzg.reflect; 2 3 public class Person { 4 private String name; 5 private int age; 6 public Person() { 7 System.out.println("new Person()"); 8 } 9 public Person(String name) { 10 this.name = name; 11 System.out.println("new Person(String name)"); 12 } 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 System.out.println("setName("+name+")"); 18 this.name = name; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 public void sayHello() { 27 System.out.println("hello"); 28 } 29 }
TestPerson.java
1 package com.hzg.reflect.test; 2 3 import java.io.File; 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.Field; 6 import java.lang.reflect.Method; 7 import java.lang.reflect.Modifier; 8 import java.net.URL; 9 10 import org.junit.Test; 11 12 import com.hzg.reflect.Person; 13 14 public class TestPerson { 15 16 /** 17 * 创建对象 18 */ 19 @Test 20 public void newObject() { 21 /* Person p = new Person(); 22 p.setName("tom"); 23 p.setAge(20); 24 p.sayHello();*/ 25 } 26 27 /** 28 * 通过反射创建对象 29 */ 30 @Test 31 public void newObjectInReflect() throws Exception{ 32 Class<Person> clazz = Person.class; 33 // getName()是类的完整类名 34 //String name = clazz.getName(); 35 String sname = clazz.getSimpleName(); 36 System.out.println(sname); 37 Person person = clazz.newInstance(); 38 System.out.println(person); 39 } 40 41 @Test 42 public void testConstructor() throws Exception{ 43 Class<Person> clazz = Person.class; 44 // 得到类的构造函数 45 Constructor<Person> ctor = clazz.getDeclaredConstructor(); 46 ctor.setAccessible(true); 47 Object obj = ctor.newInstance(); 48 System.out.println(obj); 49 } 50 51 @Test 52 public void testConstructor2() throws Exception{ 53 Class<Person> clazz = Person.class; 54 // 得到类的构造函数 55 Constructor<Person> ctor = clazz.getDeclaredConstructor(String.class); 56 Object obj = ctor.newInstance("jerry"); 57 System.out.println(obj); 58 } 59 60 @Test 61 public void testMethod() throws Exception{ 62 Class<Person> clazz = Person.class; 63 64 Object obj = clazz.newInstance(); 65 Method m = clazz.getMethod("setName", String.class); 66 // p.setName("tomas"); 67 m.invoke(obj, "tomas"); 68 System.out.println("over"); 69 System.out.println(obj); 70 } 71 72 @Test 73 public void getMethods() throws Exception { 74 Class<Person> clazz = Person.class; 75 //Method[] methods = clazz.getDeclaredMethods();//类中声明的方法 76 Method[] methods = clazz.getMethods();//获得类的公有方法 77 for (Method m: methods) { 78 String name = m.getName(); 79 System.out.println(name); 80 //System.out.println(m); 81 } 82 } 83 84 /** 85 * 字段描述符 86 */ 87 @Test 88 public void testField() throws Exception { 89 Class<Person> clazz = Person.class; 90 Person obj = clazz.newInstance(); 91 92 // 获得字段描述符 93 Field f = clazz.getDeclaredField("name"); 94 95 // 设置可访问性 96 f.setAccessible(true); 97 98 // 设置字段值 === this.name = "tom"; 99 f.set(obj, "tom"); 100 101 // 取出字段值 102 Object object = f.get(obj); 103 104 System.out.println(object); 105 106 System.out.println(obj.getName()); 107 108 } 109 110 /** 111 * Modifier:修饰符 112 * @throws IllegalAccessException 113 * @throws InstantiationException 114 */ 115 @Test 116 public void testModifer() throws Exception { 117 Class<Person> clazz = Person.class; 118 Method m = clazz.getDeclaredMethod("setName", String.class); 119 // 得到方法的修饰符总和 120 int modifer = m.getModifiers(); 121 System.out.println(Modifier.isPublic(modifer)); 122 } 123 124 /** 125 * 得到指定包下的所有类 126 * @throws Exception 127 */ 128 @Test 129 public void getclasses() throws Exception { 130 Class clazz = Person.class; 131 ClassLoader loader = clazz.getClassLoader(); 132 // 统一资源定位符 133 URL url = loader.getResource("com/hzg/reflect"); 134 135 // 文件夹 136 File file = new File(url.toURI()); 137 File[] files = file.listFiles(); 138 for (File f : files) { 139 String fname = f.getName(); 140 if (!fname.endsWith(".class")) { 141 continue; 142 } 143 String className = fname.substring(0, fname.lastIndexOf(".")); 144 className = "com.hzg.reflect." + className; 145 clazz = Class.forName(className); 146 System.out.println(clazz); 147 } 148 149 } 150 151 /** 152 * 属性复制 153 * @throws IllegalAccessException 154 * @throws IllegalArgumentException 155 */ 156 @Test 157 public void testPropertyCopy() throws Exception { 158 // 源对象 159 Person src = new Person(); 160 src.setName("tom"); 161 src.setAge(20); 162 163 // 目标对象 164 Person target = new Person(); 165 166 Class clazz = Person.class; 167 Field[] fs = clazz.getDeclaredFields(); 168 for (Field f : fs) { 169 String fname = f.getName(); 170 // 判断是否可以访问,设置可访问性 171 if (!f.isAccessible()) { 172 f.setAccessible(true); 173 } 174 // 获得该字段在src对象上对应的值 175 Object fvalue = f.get(src); 176 f.set(target, fvalue); 177 } 178 System.out.println("over"); 179 180 } 181 }
内省
专业操作javabean
对象复制
// Animal.java
1 package com.hzg.reflect; 2 3 public abstract class Animal { 4 private String name; 5 6 public String getName() { 7 return name; 8 } 9 10 public void setName(String name) { 11 this.name = name; 12 } 13 14 }
// Dog.java
1 package com.hzg.reflect; 2 3 public class Dog extends Animal{ 4 5 private String blood; 6 7 public String getBlood() { 8 return blood; 9 } 10 11 public void setBlood(String blood) { 12 this.blood = blood; 13 } 14 15 }
// TestPerson2.java
1 package com.hzg.reflect.test; 2 3 import java.io.File; 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.Field; 6 import java.lang.reflect.Method; 7 import java.lang.reflect.Modifier; 8 import java.net.URL; 9 10 import org.junit.Test; 11 12 import com.hzg.reflect.Dog; 13 import com.hzg.reflect.Person; 14 15 public class TestPerson2 { 16 17 /** 18 * 属性复制 19 * 20 * @throws IllegalAccessException 21 * @throws IllegalArgumentException 22 */ 23 @Test 24 public void testPropertyCopy2() throws Exception { 25 // 源对象 26 Dog src = new Dog(); 27 src.setName("tom"); 28 src.setBlood("A"); 29 30 // 目标对象 31 Dog target = new Dog(); 32 33 Class clazz = Dog.class; 34 Field[] fs = clazz.getDeclaredFields(); 35 for (Field f : fs) { 36 String fname = f.getName(); 37 Class<?> type = f.getType(); 38 System.out.println(type); 39 // 判断是否可以访问,设置可访问性 40 if (!f.isAccessible()) { 41 f.setAccessible(true); 42 } 43 // 获得该字段在src对象上对应的值 44 Object fvalue = f.get(src); 45 f.set(target, fvalue); 46 } 47 System.out.println("over"); 48 49 } 50 51 /** 52 * 得到整个类家族树定义的所有字段 53 */ 54 @Test 55 public void getAllFields() { 56 Class clazz = Dog.class; 57 printFields(clazz); 58 } 59 60 /** 61 * 打印字段 62 */ 63 private void printFields(Class clazz) { 64 /*if (clazz == Object.class) { 65 return; 66 }*/ 67 if (clazz == null) { 68 return; 69 } 70 Field[] fs = clazz.getDeclaredFields(); 71 if (fs != null && fs.length > 0) { 72 for (Field f : fs) { 73 Class ftype = f.getType(); 74 String fname = f.getName(); 75 System.out.println(ftype + " " + fname); 76 } 77 } 78 79 clazz = clazz.getSuperclass(); 80 printFields(clazz); 81 82 83 } 84 }
// TestIntrospector.java
1 package com.hzg.reflect.test; 2 3 import java.beans.BeanInfo; 4 import java.beans.Introspector; 5 import java.beans.PropertyDescriptor; 6 import java.lang.reflect.Method; 7 8 import org.junit.Test; 9 10 import com.hzg.reflect.Dog; 11 12 /** 13 * 内省,专业操作javabean 14 * @author zhengguohuang 15 * 16 */ 17 public class TestIntrospector { 18 /** 19 * 20 * @throws Exception 21 */ 22 @Test 23 public void testIntrospective() throws Exception{ 24 // 得到bean信息 25 BeanInfo bi = Introspector.getBeanInfo(Dog.class); 26 PropertyDescriptor[] pds = bi.getPropertyDescriptors(); 27 for (PropertyDescriptor pd : pds) { 28 // getXxx() 29 Method getter = pd.getReadMethod(); 30 System.out.println(getter); 31 // setXxx() 32 Method setter = pd.getWriteMethod(); 33 System.out.println(setter); 34 //getter.invoke(, args) 35 //System.out.println(pd.getName()); 36 } 37 } 38 }
使用内省实现对象的属性复制
1 package com.hzg.reflect.test; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.InputStream; 6 import java.net.URISyntaxException; 7 import java.net.URL; 8 9 import org.junit.Test; 10 11 /** 12 * 测试类加载器 13 * 14 * @author zhengguohuang 15 * 16 */ 17 public class TestClassLoader { 18 19 /** 20 * 获得资源url 21 * @throws Exception 22 * 23 */ 24 @Test 25 public void testClassLoader1() throws Exception { 26 ClassLoader loader = ClassLoader.getSystemClassLoader(); 27 // 搜索类路径获取资源 28 URL url = loader.getResource("com/hzg/reflect/background.jpg"); 29 File file = new File(url.toURI()); 30 System.out.println(file.length()); 31 System.out.println(loader); 32 } 33 34 /** 35 * 获得资源流 36 * @throws Exception 37 * 38 */ 39 @Test 40 public void testResourceStream() throws Exception { 41 ClassLoader loader = ClassLoader.getSystemClassLoader(); 42 // 搜索类路径获取资源 43 InputStream is = loader.getResourceAsStream("com/hzg/reflect/background.jpg"); 44 45 byte[] bytes = new byte[is.available()]; 46 is.read(); 47 is.close(); 48 new FileOutputStream("d:/xxx.jpg").write(bytes); 49 System.out.println(loader); 50 } 51 52 /** 53 * 获得系统资源 54 * @throws Exception 55 * 56 */ 57 @Test 58 public void testSystemResource() throws Exception { 59 InputStream is = ClassLoader.getSystemResourceAsStream("java/lang/String.class"); 60 System.out.println(is.available()); 61 } 62 63 /** 64 * @throws Exception 65 * 66 */ 67 @Test 68 public void testLuncher() throws Exception { 69 // have not access 70 // sun.misc.Launcher l = new sun.misc.Launcher(); 71 Class clazz = Class.forName("sun.misc.Launcher"); 72 Object object = clazz.newInstance(); 73 System.out.println(object);// sun.misc.Launcher@4459eb14 74 75 } 76 }
动态代理
不改变源码,增加新的功能
// Person.java
1 package com.hzg.reflect; 2 3 public class Person { 4 private String name; 5 private int age; 6 public Person() { 7 System.out.println("new Person()"); 8 } 9 public Person(String name) { 10 this.name = name; 11 System.out.println("new Person(String name)"); 12 } 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 System.out.println("setName("+name+")"); 18 this.name = name; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 public void sayHello() { 27 System.out.println("hello"); 28 } 29 }
// PersonDao.java
1 package com.hzg.reflect.proxy; 2 3 import com.hzg.reflect.Person; 4 5 /** 6 * Dao:data access object 7 * @author zhengguohuang 8 * 9 */ 10 public interface PersonDao { 11 12 public void insert(Person p); 13 14 public void update(Person p); 15 }
// PersonDao2.java
1 package com.hzg.reflect.proxy; 2 3 import com.hzg.reflect.Person; 4 5 /** 6 * Dao:data access object 7 * @author zhengguohuang 8 * 9 */ 10 public interface PersonDao2 { 11 12 public void insert2(Person p); 13 14 public void update2(Person p); 15 }
// PersonDaoImpl.java
1 package com.hzg.reflect.proxy; 2 3 import com.hzg.reflect.Person; 4 5 /** 6 * Dao实现类 7 * @author zhengguohuang 8 * 9 */ 10 public class PersonDaoImpl implements PersonDao, PersonDao2{ 11 12 @Override 13 public void insert(Person p) { 14 System.out.println("insert"); 15 } 16 17 @Override 18 public void update(Person p) { 19 System.out.println("update"); 20 } 21 22 @Override 23 public void insert2(Person p) { 24 System.out.println("insert2"); 25 } 26 27 @Override 28 public void update2(Person p) { 29 System.out.println("update2"); 30 } 31 32 }
// MyInvovationHandler.java
1 package com.hzg.reflect.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 public class MyInvocationHandler implements InvocationHandler { 7 8 private Object target; 9 10 public MyInvocationHandler(Object target) { 11 this.target = target; 12 } 13 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 System.out.println("hello");// 调用方法之前 17 Object ret = method.invoke(target, args); 18 System.out.println("over");// To do ... after invoke 19 return ret; 20 } 21 22 }
// App.java
1 package com.hzg.reflect.proxy; 2 3 import java.lang.reflect.Proxy; 4 5 import com.hzg.reflect.Person; 6 7 public class App { 8 9 public static void main(String[] args) { 10 ClassLoader loader = ClassLoader.getSystemClassLoader(); 11 Class[] interfaces = {PersonDao.class, PersonDao2.class}; 12 PersonDao dao = new PersonDaoImpl(); 13 MyInvocationHandler h = new MyInvocationHandler(dao); 14 15 Object proxy = (PersonDao)Proxy.newProxyInstance(loader, interfaces, h); 16 ((PersonDao)proxy).insert(new Person()); 17 ((PersonDao)proxy).update(null); 18 ((PersonDao2)proxy).insert2(null); 19 ((PersonDao2)proxy).update2(null); 20 } 21 22 }