一,先看一下反射的概念:
主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!
二,反射机制的作用:
1,反编译:.class-->.java
2,通过反射机制访问java对象的属性,方法,构造方法等;
三,在这里先看一下sun为我们提供了那些反射机制中的类:
java.lang.Class;
java.lang.reflect.Constructor; java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
四,具体功能实现:
//1. 反射机制获取类有三种方法,我们来获取Employee类型 //第一种方法: Class c1=Class.forName("Employee"); //第二种方法:每个类型都有class属性: Class c2=Employee.class; //第三种方法: 任何一个对象都有getClass方法 Employee=new Employee(); Class c3=e.getClass(); //2. 创建对象:利用newInstance; Class c=Class.forName("Employee"); Object o=c.newInstance(); //调用了Employee的无参构造函数 //3. 获取属性: 分为所有哦的属性和指定的属性 //a. 获取所有的属性: Class c=Class.forName("java.lang.Integer"); Field[] fs=c.getDeclaredFields(); //可变长字符串,存储属性 StringBuffer sb= new StringBuffer(); //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class"+ c.getSimpleName()+ "{\n"); //里面的每一个属性 for(Field field:fs){ sb.append("\t"); //空格 sb.append(Modifier.toString(field.getDeclaredFields())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName()+"");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb); //获取特定的属性 public static void main(String[] args) throws Exception{ //获取类 Class c=Class.forName("User"); //获取id属性 Field idF=c.getDeclaredFields("id"); //实例化这个类赋给o Object o=c.newInstance(); //打破封装 //使用反射机制可以打破封装性,导致了java对象的属性不安全。 idF.setAccessible(true); //给o对象的id属性赋值"110" idF.set(o,"110"); System.out.println(idF.get(o)); }
方法关键字 | 含义 |
getDeclaredMethods() | 获取所有的方法 |
getReturnType() | 获得方法的放回类型 |
getParameterTypes() | 获得方法的传入参数类型 |
getDeclaredMethod("方法名",参数类型.class,……) | 获得特定的方法 |
|
|
构造方法关键字 | 含义 |
getDeclaredConstructors() | 获取所有的构造方法 |
getDeclaredConstructor(参数类型.class,……) | 获取特定的构造方法 |
|
|
父类和父接口 | 含义 |
getSuperclass() | 获取某类的父类 |
getInterfaces() | 获取某类实现的接口 |
//1. 通过一个对象获得完整的包名和类名 package Reflect; class Dome{ 。。。 } class hello{ public static void main(String[] args){ Demo demo=new Demo(); System.out.println(demo.getClass().getName()); } } 结果: Reflect.Dome //2. 实例化Class类对象 packa Reflect; class Demo{ ... } class hello{ public static void main(String[] args){ Class<?> demo1=null; Class<?> demo2=null; Class<?> demo3=null; try{ demo1=Class.forName("Reflect.Demo"); }catch(Exception e){ e.printStackTrace(); } demo2=new Demo().getClass(); demo3=Demo.class; System.out.println("类名称 "+demo1.getName()); System.out.println("类名称 "+demo2.getName()); System.out.println("类名称 "+demo3.getName()); } } 结果: 类名称 Reflect.Demo 类名称 Reflect.Demo 类名称 Reflect.Demo //3. 通过Class实例化其他类的对象 通过无参构造实例化对象 package Reflect; class Person{ public String getName(){ return name; } public void setName(String name){ this.name=name; } public int getAge(){ return age; } public void setAge(int age){ this.age=age; } public String toString(){ return "[" +this.name+" "+this.age+"]"; } private String name; private int age; } class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Person per=null; try{ per=(Person) demo.newInstance(); }catch(InstantiationException e){ e.printStackTrace(); }catch(IllegalAccessException e){ e.printStackTrace(); } per.setName("Rollen"); per.setAge(20); System.out.println(per); } } 结果:[Rollen 20] 但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误: 比如我定义了一个构造函数: public Person(String name, int age) { this.age=age; this.name=name; } 然后继续运行上面的程序,会出现: java.lang.InstantiationException: Reflect.Person at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at Reflect.hello.main(hello.java:39) Exception in thread "main" java.lang.NullPointerException at Reflect.hello.main(hello.java:47) 所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数 //4. 通过Class调用其他类的构造函数 package Reflect; import java.lang.reflect.Constructor; class Person{ public Person(){ } public Person(String name){ this.name=name; } public Person(int age){ this.age=age; } public Person(String name, int age){ this.age=age; this.name=name; } public String getName(){ return name; } public int getAge(){ return age; } public String toString(){ return "["+this.name+""+this.age+"]"; } private String name; private int age; } class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Person per1=null; Person per2=null; Person per3=null; Person per4=null; Constructor<?> cons[]=demo.getConstructors(); try{ per1=(Person)cons[0].newInstance(); per2=(Person)cons[1].newInstance("Rollen"); per3=(Person)cons[2].newInstance(20); per4=(Person)cons[3].newInstance("Rollen",20); }catch(Exception e){ e.printStackTrace(); } System.out.println(per1); System.out.println(per2); System.out.println(per3); System.out.println(per4); } } 结果: [null 0] [Rollen 0] [null 20] [Rollen 20] //5. 返回一个类实现的接口 package Reflect; interface China{ public static final String name="Rollen"; public static int age=20; public void sayChina(); public void sayHello(String name, int age); } class Person implements China{ public Person(){ } public Person(String sex){ this.sex=sex; } public String getSex(){ return sex; } public void sayChina(){ System.out.println("hello,china"); } public void sayHello(String name,int age){ System.out.println(name+" "+age); } private String sex; } public class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Class.getName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Class<?> intes[]=demo.getInterfaces(); for(int i=0; i<intes.length;i++){ System.out.println("实现的接口 "+ inters[i].getName()); } } } 结果: 实现的接口 Reflect.China // 6. 取得其他类中的父类 class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Class<?> temp=demo.getSuperclass(); System.out.println("继承的父类为: "+temp.getName()); } } 结果:继承的父类为: java.lang.Object //7. 获得其他类中的全部构造函数 class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Constructor<?> cons[]=demo.getConstructors(); for (int i=0; i<cons.length;i++){ System.out.println("构造方法:"+cons[i]); } } } 结果: 构造方法: public Reflect.Person() 构造方法: public Reflect.Person(java.lang.String) //8. 获取构造函数修饰符 class hello{ public static void main(String[] args){ Clss<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } Constructor<?> cons[]=demo.getConstructors(); for(int i=0; i<cons.length;i++){ Class<?> p[]=cons[i].getParameterTypes(); System.out.print("构造函数: "); int mo=cons[i].getModifiers(); System.out.print(Modifier.toString(mo)+""); System.out.print(cons[i].getName()); System.out.print("("); for(int j=0;j<length;j++){ System.out.print(p[j].getName()+" arg"+i); if(j<p.length-1){ System.out.print(","); } } System.out.println("){}"); } } } 结果: 构造方法: public Reflect.Person(){} 构造方法: public Reflect.Person(java.lang.String arg1){} //9. 取得类的全部属性 class hello{ public static void main(String[] args){ Class<?> demo= null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } System.out.println("=====本类属性====="); Field[] field=demo.getDeclaredFields(); for(int i=0;i<field.length;i++){ //权限修饰符 int mo=field[i].getModifiers(); String priv=Modifier.toString(mo); //属性类型 Class<?> type=field[i].getType(); System.out.println(priv+" "+type.getName()+""+field[i].getName()+";"); } System.out.println("=====实现的接口或父类的属性====="); //取得实现的接口或父类的属性 Field[] field1=demo.getFields(); for(int j=0;i<field1.length;j++){ //权限修饰符 int mo=filed1[j].getModifiers(); String priv=Modifier.toString(mo); //属性类型 Class<?> type=filed1[j].getType(); System.out.println(priv+""+type.getName()+""+field1[j].getName()+";"); } } } 结果: ===============本类属性======================== private java.lang.String sex; ===============实现的接口或者父类的属性======================== public static final java.lang.String name; public static final int age; //10.调用其他类中的方法 class hello{ public static void main(String[] args){ Class<?> demo=null; try{ demo=Clss.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } try{ Method method=demo.getMethod("sayChina"); method.invoke(demo.newInstance()); method=demo.getMethod("sayChina",String.class,int.class); method.invoke(demo.newInstance(),"Rollen",20); }catch(Exception e){ e.printStackTrace(); } } } 结果: hello ,china Rollen 20 //11. 调用其他类的set和get方法 class hello{ public static void main(String[] args){ Class<?> demo=null; Object obj=null; try{ demo=Class.forName("Reflect.Person"); }catch(Exception e){ e.printStackTrace(); } try{ obj=demo.newInstance(); }catch(Exception e){ e.printStackTrace(); } setter(obj,"Sex","男",String.class); getter(obj,"Sex"); } /** * @param obj * 操作的对象 * @param att * 操作的属性 * */ public static void getter(Object obj, String att) { try { Method method = obj.getClass().getMethod("get" + att); System.out.println(method.invoke(obj)); } catch (Exception e) { e.printStackTrace(); } } /** * @param obj * 操作的对象 * @param att * 操作的属性 * @param value * 设置的值 * @param type * 参数的属性 * */ public static void setter(Object obj, String att, Object value, Class<?> type) { try { Method method = obj.getClass().getMethod("set" + att, type); method.invoke(obj, value); } catch (Exception e) { e.printStackTrace(); } } } 结果: 男 //12. 1)通过反射取得并修改数组的信息: import java.lang.reflect.*; class hello{ public static void main(String[] args){ int[] temp={1,2,3,4,5}; Class<?> demo=temp.getClass().getComponentType(); System.out.println("数组类型: "+demo.getName()); System.out.println("数组长度: "+Array.getLength((temp)); System.out.println("数组的第一个元素:"Array.get(temp,0)); Array.set(temp,0,100); System.out.println("修改之后数组第一个元素为:"+Array.get(temp,0)); } } 结果: 数组类型: int 数组长度 5 数组的第一个元素: 1 修改之后数组第一个元素为: 100 //12. 2)反射修改数组大小 class hello{ public static void main(String[] args) { int[] temp={1,2,3,4,5,6,7,8,9}; int[] newTemp=(int[])arrayInc(temp,15); print(newTemp); System.out.println("====================="); String[] atr={"a","b","c"}; String[] str1=(String[])arrayInc(atr,8); print(str1); } /** * 修改数组大小 * */ public static Object arrayInc(Object obj,int len){ Class<?>arr=obj.getClass().getComponentType(); Object newArr=Array.newInstance(arr, len); int co=Array.getLength(obj); System.arraycopy(obj, 0, newArr, 0, co); return newArr; } /** * 打印 * */ public static void print(Object obj){ Class<?>c=obj.getClass(); if(!c.isArray()){ return; } System.out.println("数组长度为: "+Array.getLength(obj)); for (int i = 0; i < Array.getLength(obj); i++) { System.out.print(Array.get(obj, i)+" "); } } } 结果: 数组长度为: 15 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 ===================== 数组长度为: 8 a b c null null null null null