1、java 反射常用方法(面试常见) 在 JDK 中,主要由以下类来实现 Java 反射机制,这些类都位于 java.lang.reflect 包中:1.Class 类:代表一个类。2.Field 类:代表类的成员变量(成员变量也称为类的属性) 。3.Method 类:代表类的方法。4.Constructor 类:代表类的构造方法。5.Array 类:提供了动态创建数组,以及访问数组元素的静态方法。.Class 类在 java.lang.Object 类中定义了 getClass()方法,因此对于任意一个 Java 对象,都可以通过此方法获得对象的类型。Class 类是 Reflection A
2、PI 中的核心类,它有以下方法(1)获得对象的类型:getName():获得类的完整名字。getFields():获得类的 public 类型的属性。getDeclaredFields():获得类的所有属性。getMethods():获得类的 public 类型的方法。getDeclaredMethods():获得类的所有方法。getMethod(String name, Class parameterTypes):获得类的特定方法, name 参数指定方法的名字,parameterTypes 参数指定方法的参数类型。getConstrutors():获得类的 public 类型的构造方法。g
3、etConstrutor(Class parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。newInstance():通过类的不带参数的构造方法创建这个类的一个对象。(2)通过默认构造方法创建一个新的对象:Object objectCopy=classType.getConstructor(new Class).newInstance(new Object);(3)获得对象的所有属性:Field fields=classType.getDeclaredFields();Class 类的 getDeclaredFields()方法返回类
4、的所有属性,包括 public、protected、默认和private 访问级别的属性。以上代码先调用 Class 类的 getConstructor()方法获得一个 Constructor 对象,它代表默认的构造方法,然后调用 Constructor 对象的 newInstance()方法构造一个实例。(4)获得每个属性相应的 getXXX()和 setXXX()方法,然后执行这些方法,把原来对象的属性复制到新的对象中:推荐阅读:http:/ view plaincopyprint?1. Field field=fieldsi; 2. String fieldName=field.getN
5、ame(); 3. String firstLetter=fieldName.substring(0,1).toUpperCase(); 4. /获得和属性对应的 getXXX()方法的名字String getMethodName=“get“+firstLetter+fieldName.substring(1); 5. /获得和属性对应的 setXXX()方法的名字String setMethodName=“set“+firstLetter+fieldName.substring(1); 6. /获得和属性对应的 getXXX()方法 7. Method getMethod=classType
6、.getMethod(getMethodName,new Class); 8. /获得和属性对应的 setXXX()方法 9. Method setMethod=classType.getMethod(setMethodName,new Classfield.getType(); 10. /调用原对象的 getXXX()方法 11. Object value=getMethod.invoke(object,new Object); 12. System.out.println(fieldName+“:“+value); 13. /调用复制对象的 setXXX()方法 14. setMethod
7、.invoke(objectCopy,new Objectvalue); .Method 类的 invoke(Object obj,Object args)方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么 invoke()方法会把它转换为相应的包装类型的对象,再将其返回。.Array 类java.lang.Array 类提供了动态创建和访问数组元素的各种静态方法。如例程 10-4 所示的ArrayTester1 类的 main()方法创建了一个长度为 10 的字符串数组,接
8、着把索引位置为 5的元素设为“hello”,然后再读取索引位置为 5 的元素的值。java view plaincopyprint?1. import java.lang.reflect.*; 2. public class ArrayTester1 3. public static void main(String args)throws Exception 4. Class classType = Class.forName(“java.lang.String“); 5. /创建一个长度为 10 的字符串数组 6. Object array = Array.newInstance(clas
9、sType, 10); 7. /把索引位置为 5 的元素设为“hello“ 8. Array.set(array, 5, “hello“); 9. /读取索引位置为 5 的元素的值 10. String s = (String) Array.get(array, 5); 11. System.out.println(s); 12. 13. java 反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解。下面开始正文。【案例 1】通过一个对象获得完整的包名和类名java view
10、plaincopyprint?1. package Reflect; 2. 3. /* 4. * 通过一个对象获得完整的包名和类名 5. * */ 6. class Demo 7. /other codes. 8. 9. 10. class hello 11. public static void main(String args) 12. Demo demo=new Demo(); 13. System.out.println(demo.getClass().getName(); 14. 15. 好看的小说:http:/ Class 的实例。【案例 2】实例化 Class 类对象java v
11、iew plaincopyprint?1. package Reflect; 2. class Demo 3. /other codes. 4. 5. 6. class hello 7. public static void main(String args) 8. Class demo1=null; 9. Class demo2=null; 10. Class demo3=null; 11. try 12. /一般尽量采用这种形式 13. demo1=Class.forName(“Reflect.Demo“); 14. catch(Exception e) 15. e.printStackT
12、race(); 16. 17. demo2=new Demo().getClass(); 18. demo3=Demo.class; 19. 20. System.out.println(“类名称 “+demo1.getName(); 21. System.out.println(“类名称 “+demo2.getName(); 22. System.out.println(“类名称 “+demo3.getName(); 23. 24. 25. 【运行结果】:类名称 Reflect.Demo类名称 Reflect.Demo类名称 Reflect.Demo【案例 3】通过 Class 实例化其他类
13、的对象通过无参构造实例化对象java view plaincopyprint?1. package Reflect; 2. 3. class Person 4. 5. public String getName() 6. return name; 7. 8. public void setName(String name) 9. this.name = name; 10. 11. public int getAge() 12. return age; 13. 14. public void setAge(int age) 15. this.age = age; 16. 17. Override
14、 18. public String toString() 19. return “+this.name+“ “+this.age+“; 20. 21. private String name; 22. private int age; 23. 24. 25. class hello 26. public static void main(String args) 27. Class demo=null; 28. try 29. demo=Class.forName(“Reflect.Person“); 30. catch (Exception e) 31. e.printStackTrace
15、(); 32. 33. Person per=null; 34. try 35. per=(Person)demo.newInstance(); 36. catch (InstantiationException e) 37. / TODO Auto-generated catch block 38. e.printStackTrace(); 39. catch (IllegalAccessException e) 40. / TODO Auto-generated catch block 41. e.printStackTrace(); 42. 43. per.setName(“Rollen
16、“); 44. per.setAge(20); 45. System.out.println(per); 46. 47. 【运行结果】:Rollen 20但是注意一下,当我们把 Person 中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:比如我定义了一个构造函数:java view plaincopyprint?1. public Person(String name, int age) 2. this.age=age; 3. this.name=name; 4. 然后继续运行上面的程序,会出现:java.lang.InstantiationExce
17、ption: Reflect.Personatjava.lang.Class.newInstance0(Class.java:340)atjava.lang.Class.newInstance(Class.java:308)atReflect.hello.main(hello.java:39)Exception in thread “main“ java.lang.NullPointerExceptionatReflect.hello.main(hello.java:47)所以大家以后再编写使用 Class 实例化其他类的对象的时候,一定要自己定义无参的构造函数 【案例】通过 Class 调用
18、其他类中的构造函数(也可以通过这种方式通过 Class 创建其他类的对象)java view plaincopyprint?1. package Reflect; 2. 3. import java.lang.reflect.Constructor; 4. 5. class Person 6. 7. public Person() 8. 9. 推荐阅读:http:/ public Person(String name) 11. this.name=name; 12. 13. public Person(int age) 14. this.age=age; 15. 16. public Pers
19、on(String name, int age) 17. this.age=age; 18. this.name=name; 19. 20. public String getName() 21. return name; 22. 23. public int getAge() 24. return age; 25. 26. Override 27. public String toString() 28. return “+this.name+“ “+this.age+“; 29. 30. private String name; 31. private int age; 32. 33. 3
20、4. class hello 35. public static void main(String args) 36. Class demo=null; 37. try 38. demo=Class.forName(“Reflect.Person“); 39. catch (Exception e) 40. e.printStackTrace(); 41. 42. Person per1=null; 43. Person per2=null; 44. Person per3=null; 45. Person per4=null; 46. /取得全部的构造函数 47. Constructor c
21、ons=demo.getConstructors(); 48. try 49. per1=(Person)cons0.newInstance(); 50. per2=(Person)cons1.newInstance(“Rollen“); 51. per3=(Person)cons2.newInstance(20); 52. per4=(Person)cons3.newInstance(“Rollen“,20); 53. catch(Exception e) 54. e.printStackTrace(); 55. 56. System.out.println(per1); 57. Syste
22、m.out.println(per2); 58. System.out.println(per3); 59. System.out.println(per4); 60. 61. 【运行结果】:null 0Rollen 0null 20Rollen 20【案例】 返回一个类实现的接口:java view plaincopyprint?1. package Reflect; 2. 3. interface China 4. public static final String name=“Rollen“; 5. public static int age=20; 6. public void sa
23、yChina(); 7. public void sayHello(String name, int age); 8. 9. 10. class Person implements China 11. public Person() 12. 13. 14. public Person(String sex) 15. this.sex=sex; 16. 17. public String getSex() 18. return sex; 19. 20. public void setSex(String sex) 21. this.sex = sex; 22. 23. Override 24.
24、public void sayChina() 25. System.out.println(“hello ,china“); 26. 27. Override 28. public void sayHello(String name, int age) 29. System.out.println(name+“ “+age); 30. 31. private String sex; 32. 33. 34. class hello 35. public static void main(String args) 36. Class demo=null; 37. try 38. demo=Clas
25、s.forName(“Reflect.Person“); 39. catch (Exception e) 40. e.printStackTrace(); 41. 42. /保存所有的接口 43. Class intes=demo.getInterfaces(); 44. for (int i = 0; i demo=null; 4. try 5. demo=Class.forName(“Reflect.Person“); 6. catch (Exception e) 7. e.printStackTrace(); 8. 9. /取得父类 10. Class temp=demo.getSupe
26、rclass(); 11. System.out.println(“继承的父类为: “+temp.getName(); 12. 13. 【运行结果】继承的父类为: java.lang.Object【案例】:获得其他类中的全部构造函数这个例子需要在程序开头添加 import java.lang.reflect.*;然后将主类编写为:java view plaincopyprint?1. class hello 2. public static void main(String args) 3. Class demo=null; 4. try 5. demo=Class.forName(“Refl
27、ect.Person“); 6. catch (Exception e) 7. e.printStackTrace(); 8. 9. Constructorcons=demo.getConstructors(); 10. for (int i = 0; i demo=null; 4. try 5. demo=Class.forName(“Reflect.Person“); 6. catch (Exception e) 7. e.printStackTrace(); 8. 9. Constructorcons=demo.getConstructors(); 10. for (int i = 0;
28、 i p=consi.getParameterTypes(); 12. System.out.print(“构造方法: “); 13. int mo=consi.getModifiers(); 14. System.out.print(Modifier.toString(mo)+“ “); 15. System.out.print(consi.getName(); 16. System.out.print(“(“); 17. for(int j=0;j demo=null; 4. try 5. demo=Class.forName(“Reflect.Person“); 6. catch (Ex
29、ception e) 7. e.printStackTrace(); 8. 9. Method method=demo.getMethods(); 10. for(int i=0;i returnType=methodi.getReturnType(); 12. Class para=methodi.getParameterTypes(); 13. int temp=methodi.getModifiers(); 14. System.out.print(Modifier.toString(temp)+“ “); 15. System.out.print(returnType.getName(
30、)+“ “); 16. System.out.print(methodi.getName()+“ “); 17. System.out.print(“(“); 18. for(int j=0;j exce=methodi.getExceptionTypes(); 25. if(exce.length0) 26. System.out.print(“) throws “); 27. for(int k=0;k demo = null; 4. try 5. demo = Class.forName(“Reflect.Person“); 6. catch (Exception e) 7. e.pri
31、ntStackTrace(); 8. 9. System.out.println(“=本类属性=“); 10. / 取得本类的全部属性 11. Field field = demo.getDeclaredFields(); 12. for (int i = 0; i type = fieldi.getType(); 18. System.out.println(priv + “ “ + type.getName() + “ “ 19. + fieldi.getName() + “;“); 20. 21. System.out.println(“=实现的接口或者父类的属性=“); 22. / 取
32、得实现的接口或者父类的属性 23. Field filed1 = demo.getFields(); 24. for (int j = 0; j type = filed1j.getType(); 30. System.out.println(priv + “ “ + type.getName() + “ “ 31. + filed1j.getName() + “;“); 32. 33. 34. 【运行结果】:=本类属性=private java.lang.String sex;=实现的接口或者父类的属性=public static final java.lang.Stringname;pub
33、lic static final int age;【案例】其实还可以通过反射调用其他类中的方法:java view plaincopyprint?1. class hello 2. public static void main(String args) 3. Class demo = null; 4. try 5. demo = Class.forName(“Reflect.Person“); 6. catch (Exception e) 7. e.printStackTrace(); 8. 9. try 10. /调用 Person 类中的 sayChina 方法 11. Method m
34、ethod=demo.getMethod(“sayChina“); 12. method.invoke(demo.newInstance(); 13. /调用 Person 的 sayHello 方法 14. method=demo.getMethod(“sayHello“, String.class,int.class); 15. method.invoke(demo.newInstance(),“Rollen“,20); 16. 17. catch (Exception e) 18. e.printStackTrace(); 19. 20. 21. 【运行结果】: hello ,china
35、Rollen 20【案例】调用其他类的 set 和 get 方法java view plaincopyprint?1. class hello 2. public static void main(String args) 3. Class demo = null; 4. Object obj=null; 5. try 6. demo = Class.forName(“Reflect.Person“); 7. catch (Exception e) 8. e.printStackTrace(); 9. 10. try 11. obj=demo.newInstance(); 12. catch
36、(Exception e) 13. e.printStackTrace(); 14. 15. setter(obj,“Sex“,“男 “,String.class); 16. getter(obj,“Sex“); 17. 18. 19. /* 20. * param obj 21. * 操作的对象 22. * param att 23. * 操作的属性 24. * */ 25. public static void getter(Object obj, String att) 26. try 27. Method method = obj.getClass().getMethod(“get“
37、+ att); 28. System.out.println(method.invoke(obj); 29. catch (Exception e) 30. e.printStackTrace(); 31. 32. 33. 34. /* 35. * param obj 36. * 操作的对象 37. * param att 38. * 操作的属性 39. * param value 40. * 设置的值 41. * param type 42. * 参数的属性 43. * */ 44. public static void setter(Object obj, String att, Obje
38、ct value, 45. Class type) 46. try 47. Method method = obj.getClass().getMethod(“set“ + att, type); 48. method.invoke(obj, value); 49. catch (Exception e) 50. e.printStackTrace(); 51. 52. 53. / end class 【运行结果】:男【案例】通过反射操作属性java view plaincopyprint?1. class hello 2. public static void main(String arg
39、s) throws Exception 3. Class demo = null; 4. Object obj = null; 5. 6. demo = Class.forName(“Reflect.Person“); 7. obj = demo.newInstance(); 8. 9. Field field = demo.getDeclaredField(“sex“); 10. field.setAccessible(true); 11. field.set(obj, “男“); 12. System.out.println(field.get(obj); 13. 14. / end cl
40、ass 【案例】通过反射取得并修改数组的信息:java view plaincopyprint?1. import java.lang.reflect.*; 2. class hello 3. public static void main(String args) 4. int temp=1,2,3,4,5; 5. Classdemo=temp.getClass().getComponentType(); 6. System.out.println(“数组类型: “+demo.getName(); 7. System.out.println(“数组长度 “+Array.getLength(t
41、emp); 8. System.out.println(“数组的第一个元素: “+Array.get(temp, 0); 9. Array.set(temp, 0, 100); 10. System.out.println(“修改之后数组第一个元素为: “+Array.get(temp, 0); 11. 12. 【运行结果】:数组类型:int数组长度 5数组的第一个元素:1修改之后数组第一个元素为: 100【案例】通过反射修改数组大小java view plaincopyprint?1. class hello 2. public static void main(String args) 3
42、. int temp=1,2,3,4,5,6,7,8,9; 4. int newTemp=(int)arrayInc(temp,15); 5. print(newTemp); 6. System.out.println(“=“); 7. String atr=“a“,“b“,“c“; 8. String str1=(String)arrayInc(atr,8); 9. print(str1); 10. 11. 12. /* 13. * 修改数组大小 14. * */ 15. public static Object arrayInc(Object obj,int len) 16. Classarr=obj.getClass().getComponentType(); 17. Object newArr=Array.newInstance(arr, len); 18. int co=Array.getLength(obj); 19. System.arraycopy(obj, 0, newArr, 0, co); 20. return newArr; 21. 22.