Java 反射机制详解:
1.通过一个对象获得该对象完整的包名.类名
Demo demo = new Demo(); //Demo在reflct包下 System.out.println(demo.getClass().getName()); //reflect.Demo
2.创建Class的对象(所有类的对象都是Class的对象)
1 Class<?> demo1 = null; 2 Class<?> demo2 = null; 3 Class<?> demo3 = null; 4 try { 5 //尽量采用这种方式创建class对象 6 demo1 = Class.forName("reflect.Demo"); 7 } catch (ClassNotFoundException e) { 8 e.printStackTrace(); 9 } 10 demo2 = new Demo().getClass(); 11 demo3 = Demo.class;
3.通过Class实例化其他对象
1 //创建Class对象 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Demo"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 9 //通过Class对象创建其他类对象 10 Demo demo1 = null; 11 try { 12 demo1 = (Demo) demo.newInstance(); 13 } catch (InstantiationException e) { 14 e.printStackTrace(); 15 } catch (IllegalAccessException e) { 16 e.printStackTrace(); 17 } 18 19 demo1.setAge(25); 20 demo1.setName("luotong"); 21 System.out.println(demo1.getName()+demo1.getAge());
4.通过Class调用其他类中构造函数来创建对象
1 //创建Class实例 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 9 //获得构造器 10 Constructor<?>[] constructors = demo.getConstructors(); 11 12 //利用不同的构造函数创建Person对象 13 Person person1 = null; 14 Person person2 = null; 15 try { 16 person1 = (Person) constructors[1].newInstance(12); 17 person2 = (Person) constructors[2].newInstance("luotong"); 18 } catch (InstantiationException e) { 19 e.printStackTrace(); 20 } catch (IllegalAccessException e) { 21 e.printStackTrace(); 22 } catch (InvocationTargetException e) { 23 e.printStackTrace(); 24 } 25 //输出person对象 26 System.out.println(person1.toString()); 27 System.out.println(person2.toString());
5.获得其他类实现的接口
1 //通过Class实例返回一个类实现的接口 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 9 //获得Person实现的接口 10 Class<?>[] interfaces = demo.getInterfaces(); 11 for (Class<?> anInterface : interfaces) { 12 System.out.println("person实现的接口"+anInterface.getName()); 13 }
6.获得其他类的父类
1 //取得其他类的父类 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 Class<?> superclass = demo.getSuperclass(); 9 System.out.println(superclass);
7.获得其他类的构造函数
1 //获得其他类中的全部构造函数 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 9 Constructor<?>[] constructors = demo.getConstructors(); 10 for (Constructor<?> constructor : constructors) { 11 System.out.println(constructor); 12 }
8.获得本类的全部属性
1 //获得本类的全部属性 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 Field[] declaredFields = demo.getDeclaredFields(); 9 System.out.println(declaredFields.length); 10 for (Field declaredField : declaredFields) { 11 //权限修饰符 12 int modifiers = declaredField.getModifiers(); 13 String priv = Modifier.toString(modifiers); 14 //属性类型 15 Class<?> type = declaredField.getType(); 16 System.out.println(priv + " " + type.getName() + " " + declaredField.getName() + ";"); 17 }
9.获得本类实现的接口或其父类的属性
1 //获得父类或者实现的接口的全部属性 2 Class<?> demo = null; 3 try { 4 demo = Class.forName("reflect.Person"); 5 } catch (ClassNotFoundException e) { 6 e.printStackTrace(); 7 } 8 //得到父类的属性 9 Field[] fields = demo.getFields(); 10 for (Field field : fields) { 11 //权限修饰符 12 int modifiers = field.getModifiers(); 13 String priv = Modifier.toString(modifiers); 14 //属性类型 15 Class<?> type = field.getType(); 16 System.out.println(priv + " " + type.getName() + " " + field.getName()); 17 }
10.通过反射调用其他类的方法
Class<?> person = null; try { person = Class.forName("reflect.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { //调用Person类的sayChina()方法 Method sayChina = person.getMethod("sayChina"); sayChina.invoke(person.newInstance()); //调用Person类的sayHello()方法 Method sayHello = person.getMethod("sayHello", String.class, int.class); sayHello.invoke(person.newInstance(),"luotong",26); } catch (Exception e) { e.printStackTrace(); }
11.调用其他类的set和get方法
1 public static void main(String args[]){ 2 Class<?> demo1 = null; 3 Object object = null; 4 try { 5 demo1 = Class.forName("reflect.Person"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 10 try { 11 object = demo1.newInstance(); 12 } catch (InstantiationException e) { 13 e.printStackTrace(); 14 } catch (IllegalAccessException e) { 15 e.printStackTrace(); 16 } 17 setter(object,"Sex","男",String.class); 18 getter(object,"Sex"); 19 } 20 21 /** 22 * @param obj //操作的对象 23 * @param att //操作的属性 24 */ 25 public static void getter(Object obj,String att){ 26 try { 27 Method method = obj.getClass().getMethod("get" + att); 28 System.out.println(method.invoke(obj)); 29 } catch (Exception e) { 30 e.printStackTrace(); 31 } 32 } 33 34 /** 35 * 36 * @param obj 操作的对象 37 * @param att 操作的属性 38 * @param value 设置的值 39 * @param type 参数的类型 40 */ 41 public static void setter(Object obj,String att,String value,Class<?> type){ 42 try { 43 Method method = obj.getClass().getMethod("set" + att, type); 44 method.invoke(obj,value); 45 } catch (Exception e) { 46 e.printStackTrace(); 47 } 48 }
【运行结果】 男
12.通过反射操作属性
1 Class<?> demo2 = null; 2 Object obj = null; 3 try { 4 demo2 = Class.forName("reflect.Person"); 5 obj = demo2.newInstance(); 6 Field sex = demo.getDeclaredField("sex"); 7 sex.setAccessible(true); 8 sex.set(obj,"男"); 9 System.out.println(sex.get(obj)); 10 } catch (Exception e) { 11 e.printStackTrace(); 12 }
【运行结果】 男
13.通过反射取得并修改数组
1 int[] temp = {1,2,3,4}; 2 Class<?> aClass = temp.getClass().getComponentType(); 3 System.out.println("数组类型"+aClass.getName()); 4 System.out.println("数组长度"+ Array.getLength(temp)); 5 System.out.println("数组的第一个元素"+Array.get(temp,0)); 6 Array.set(temp,0,100); //修改数组的第一个元素为100 7 System.out.println("修改后数组的第一个元素"+Array.get(temp,0));
通过反射修改数组大小(略)
动态代理:
14.如何获得类加载器
1 public static void main(String args[]){ 2 Test test = new Test(); 3 System.out.println(test.getClass().getClassLoader().getClass().getName()); 4 }
【结果】 sun.misc.Launcher$AppClassLoader
不容易记住的:
1.
getFields和getDeclaredFields区别:
getFields返回的是声明为public的属性,包括父类中定义的属性。
getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。
2.
getMethods()和getDeclaredMethods()区别:
getMethods返回本类和父类中public的方法。
getDeclaredMethods返回本类中的所有方法,不包括父类中的方法。
3.
getGenericInterface(),返回此对象所表示的类直接实现的接口。
getInterface(),返回此对象所表示的类或接口实现的接口。
4.getSuperClass(),返回某个类直接继承的父类
getGenericSuperClass(),返回某个类直接的具有泛型的父类
1 package com.guolele.web.controller; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Type; 5 6 /** 7 * Created by Administrator on 2016/6/7. 8 */ 9 public class RefConstructor { 10 11 public static void main(String[] args) throws Exception { 12 RefConstructor refConstructor = new RefConstructor(); 13 refConstructor.getConstructor(); 14 } 15 16 public void getConstructor() throws Exception { 17 Class c = null; 18 c = Class.forName("java.lang.Long"); 19 20 Class cs = java.lang.String.class; 21 22 System.out.println("----------------------------"); 23 24 Constructor constructor = c.getConstructor(cs); 25 System.out.println("通过参数获取指定Class对象的构造方法(包括父类和实现的接口中的构造方法)"); 26 System.out.println(constructor.toString()); 27 28 Constructor constructor1 = c.getDeclaredConstructor(cs); 29 System.out.println("通过参数获取指定Class对象所表示的类或接口的构造方法"); 30 System.out.println(constructor1.toString()); 31 32 Constructor constructor2 = c.getEnclosingConstructor(); 33 System.out.println("获取本地或匿名Constructor对象,它表示基础类的立即封闭构造方法。"); 34 if (constructor2 != null) { 35 System.out.println(constructor2.toString()); 36 } else { 37 System.out.println("没有获取到任何构造方法"); 38 } 39 40 Constructor[] constructors = c.getConstructors(); 41 System.out.println("获取指定Class对象的所有构造方法,包括其父类和实现的接口的构造方法"); 42 for (Constructor ct : constructors) { 43 System.out.println(ct.toString()); 44 } 45 46 System.out.println("--------------------------"); 47 48 Class[] interfaces = c.getInterfaces(); 49 System.out.println("返回实现的所有接口(包括父类实现的接口)"); 50 for (Class inf : interfaces) { 51 System.out.println(inf.toString()); 52 } 53 54 Type[] types = c.getGenericInterfaces(); 55 System.out.println("返回直接实现的接口"); 56 for (Type t : types) { 57 System.out.println(t.toString()); 58 } 59 60 Class superclass = c.getSuperclass(); 61 System.out.println("返回间接父类"); 62 System.out.println(superclass.toString()); 63 64 Type genericSuperclass = c.getGenericSuperclass(); 65 System.out.println("返回其直接继承父类"); 66 System.out.println(genericSuperclass.toString()); 67 68 System.out.println("返回实现的所有接口和父类"); 69 for (Class aClass : c.getClasses()) { 70 System.out.println(aClass.toString()); 71 } 72 } 73 }
结果:
---------------------------- 通过参数获取指定Class对象的构造方法(包括父类和实现的接口中的构造方法) public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException 通过参数获取指定Class对象所表示的类或接口的构造方法 public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException 获取本地或匿名Constructor对象,它表示基础类的立即封闭构造方法。 没有获取到任何构造方法 获取指定Class对象的所有构造方法,包括其父类和实现的接口的构造方法 public java.lang.Long(long) public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException -------------------------- 返回实现的所有接口(包括父类实现的接口) interface java.lang.Comparable 返回直接实现的接口 java.lang.Comparable<java.lang.Long> 返回间接父类 class java.lang.Number 返回其直接继承父类 class java.lang.Number 返回实现的所有接口和父类 Process finished with exit code 0