反射-Reflect
测试用到的代码
1.接口 Person.java
1 public interface Person { 2 Boolean isMale = true; 3 4 void say(); 5 6 void eat(); 7 8 void sleep(); 9 }
2. Man.java
1 public class Man implements Person { 2 private String name; 3 private int age; 4 5 public Man() { 6 } 7 8 public Man(String name) { 9 this.name = name; 10 } 11 12 public Man(int age) { 13 this.age = age; 14 } 15 16 public Man(String name, int age) { 17 this.name = name; 18 this.age = age; 19 } 20 21 private String test1(String name, int age) { 22 return name + String.valueOf(age); 23 } 24 25 @Override 26 public void say() { 27 System.out.println("I am Man"); 28 } 29 30 public void sayName(String name) { 31 System.out.println("I am " + name); 32 } 33 34 public static void sayStatic() { 35 System.out.println("This is a static method"); 36 } 37 38 public static void sayStatic2(String name) { 39 System.out.println("This is a static method,I am " + name); 40 } 41 42 @Override 43 public void eat() { 44 System.out.println("Man eat 5 breads"); 45 } 46 47 @Override 48 public void sleep() { 49 System.out.println("Man need sleep 8 hours"); 50 } 51 52 @Override 53 public String toString() { 54 return this.name + ":" + this.age; 55 } 56 }
3. Women.java
1 public class Women implements Person { 2 @Override 3 public void say() { 4 System.out.println("I am women"); 5 } 6 7 @Override 8 public void eat() { 9 System.out.println("Women eat 3 breads"); 10 } 11 12 @Override 13 public void sleep() { 14 System.out.println("Women sleep 8 hours"); 15 } 16 }
4. Child.java
1 public class Child extends Man { 2 3 @Override 4 public void say() { 5 System.out.println("I am Child"); 6 } 7 }
通过反射,获取到类的信息和操作
1.获取到类完整的包名和类名
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = Man.class; 4 String name = c.getName(); 5 System.out.println(name); 6 } 7 }
结果:
cc.lijingbo.script.reflect.Man
2.实例化 Class 类对象,有三种方法可以获取到 Class 对象。
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c1 = null; 4 Class<?> c2 = null; 5 Class<?> c3 = null; 6 7 c1 = Man.class; 8 Man man = new Man(); 9 c2 = man.getClass(); 10 try { 11 c3 = Class.forName("cc.lijingbo.script.reflect.Man"); 12 } catch (ClassNotFoundException e) { 13 e.printStackTrace(); 14 } 15 16 System.out.println("类的名称:" + c1.getName()); 17 System.out.println("类的名称:" + c2.getName()); 18 System.out.println("类的名称:" + c3.getName()); 19 } 20 }
结果:
类的名称:cc.lijingbo.script.reflect.Man
类的名称:cc.lijingbo.script.reflect.Man
类的名称:cc.lijingbo.script.reflect.Man
3. Class 类实例化 Man 类,通过 Man 类的无参构造方法
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c3 = null; 4 try { 5 c3 = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 try { 10 Man man = (Man) c3.newInstance(); 11 man.say(); 12 man.eat(); 13 man.sleep(); 14 } catch (InstantiationException e) { 15 e.printStackTrace(); 16 } catch (IllegalAccessException e) { 17 e.printStackTrace(); 18 } 19 } 20 }
结果:
I am Man Man eat 5 breads Man need sleep 8 hours
[注意]:假如类中定义了构造方法,且没有无参构造方法,使用 newInstance() 会报错,无法实例化。
Man.java 去掉无参构造方法,然后使用 Class 类实例化 Man 类。
Test.java
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c3 = null; 4 try { 5 c3 = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 try { 10 Man man = (Man) c3.newInstance(); 11 man.say(); 12 man.eat(); 13 man.sleep(); 14 } catch (InstantiationException e) { 15 e.printStackTrace(); 16 } catch (IllegalAccessException e) { 17 e.printStackTrace(); 18 } 19 } 20 }
结果:
1 java.lang.InstantiationException: cc.lijingbo.script.reflect.Man 2 at java.lang.Class.newInstance(Class.java:423) 3 at cc.lijingbo.script.reflect.ReflectTest.main(ReflectTest.java:15) 4 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 5 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 6 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 7 at java.lang.reflect.Method.invoke(Method.java:483) 8 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 9 Caused by: java.lang.NoSuchMethodException: cc.lijingbo.script.reflect.Man.<init>() 10 at java.lang.Class.getConstructor0(Class.java:3074) 11 at java.lang.Class.newInstance(Class.java:408) 12 ... 6 more
分析:
可以看到异常的是原因: Caused by: java.lang.NoSuchMethodException: cc.lijingbo.script.reflect.Man.<init>(),并重新抛出了 java.lang.InstantiationException的异常。引起的原因就是没有无参构造方法造成的。
4. 调用 Man 类中的所有构造方法,可以通过各种构造方法实例化 Man 类。
[注意]:反射获取到的所有构造方法中,注意在数组中的顺序。
Test.java
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Man m1 = null; 10 Man m2 = null; 11 Man m3 = null; 12 Man m4 = null; 13 Constructor<?>[] constructors = c.getConstructors(); 14 try { 15 m1 = (Man) constructors[3].newInstance(); 16 m2 = (Man) constructors[2].newInstance("Jerome"); 17 m3 = (Man) constructors[1].newInstance(20); 18 m4 = (Man) constructors[0].newInstance("Jerome1", 21); 19 } catch (InstantiationException e) { 20 e.printStackTrace(); 21 } catch (IllegalAccessException e) { 22 e.printStackTrace(); 23 } catch (InvocationTargetException e) { 24 e.printStackTrace(); 25 } 26 System.out.println(m1); 27 System.out.println(m2); 28 System.out.println(m3); 29 System.out.println(m4); 30 } 31 }
结果:
null:0 Jerome:0 null:20 Jerome1:21
5. 获得 Man 类中的全部构造函数
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Constructor<?>[] constructors = c.getConstructors(); 10 for (Constructor constructor : constructors) { 11 System.out.println(constructor); 12 } 13 } 14 }
结果:
1 public cc.lijingbo.script.reflect.Man(java.lang.String,int) 2 public cc.lijingbo.script.reflect.Man(int) 3 public cc.lijingbo.script.reflect.Man(java.lang.String) 4 public cc.lijingbo.script.reflect.Man()
6. 返回类实现的接口
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Class<?>[] interfaces = c.getInterfaces(); 10 for (Class in : interfaces) { 11 System.out.println(in.getName()); 12 } 13 } 14 }
结果:
cc.lijingbo.script.reflect.Person
7. 取得 Child 类的父类
Child.java
1 public class Child extends Man { 2 3 @Override 4 public void say() { 5 System.out.println("I am Child"); 6 } 7 }
Test.java
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Child"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Class<?> superclass = c.getSuperclass(); 10 System.out.println(superclass.getName()); 11 } 12 }
结果:
cc.lijingbo.script.reflect.Man
8. 获取构造方法的修饰符
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Constructor<?>[] constructors = c.getConstructors(); 10 for (int i = 0; i < constructors.length; i++) { 11 Class[] parameterTypes = constructors[i].getParameterTypes(); 12 int modifiers = constructors[i].getModifiers(); 13 System.out.print(Modifier.toString(modifiers) + " "); 14 System.out.print(constructors[i].getName()); 15 System.out.println("("); 16 for (int j = 0; j < parameterTypes.length; ++j) { 17 System.out.print(parameterTypes[j].getName() + " arg" + i); 18 if (j < parameterTypes.length - 1) { 19 System.out.print(","); 20 } 21 } 22 System.out.println("){}"); 23 } 24 } 25 }
结果:
1 public cc.lijingbo.script.reflect.Man( 2 java.lang.String arg0,int arg0){} 3 public cc.lijingbo.script.reflect.Man( 4 int arg1){} 5 public cc.lijingbo.script.reflect.Man( 6 java.lang.String arg2){} 7 public cc.lijingbo.script.reflect.Man( 8 ){}
9. 取得 Man 类的全部属性
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Field[] declaredFields = c.getDeclaredFields(); 10 for (Field field : declaredFields) { 11 int modifiers = field.getModifiers(); 12 String type = Modifier.toString(modifiers); 13 Class<?> fieldType = field.getType(); 14 System.out.println(type + " " + fieldType + " " + field.getName()); 15 } 16 System.out.println(".........."); 17 Field[] fields = c.getFields(); 18 for (Field field : fields) { 19 int modifiers = field.getModifiers(); 20 String type = Modifier.toString(modifiers); 21 Class<?> fieldType = field.getType(); 22 System.out.println(type + " " + fieldType + " " + field.getName()); 23 } 24 } 25 }
结果:
private class java.lang.String name private int age .......... public static final class java.lang.Boolean isMale
10.调用 Man 类中的方法,有参方法,无参方法,静态无参方法和静态有参方法
1 public class ReflectTest { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("cc.lijingbo.script.reflect.Man"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 10 //调用带参的方法 11 try { 12 Method sayName = c.getMethod("sayName", String.class); 13 sayName.invoke(c.newInstance(), "Jerome"); 14 } catch (NoSuchMethodException e) { 15 e.printStackTrace(); 16 } catch (IllegalAccessException e) { 17 e.printStackTrace(); 18 } catch (InstantiationException e) { 19 e.printStackTrace(); 20 } catch (InvocationTargetException e) { 21 e.printStackTrace(); 22 } 23 24 //调用无参的方法 25 try { 26 Method say = c.getMethod("say"); 27 say.invoke(c.newInstance()); 28 } catch (NoSuchMethodException e) { 29 e.printStackTrace(); 30 } catch (IllegalAccessException e) { 31 e.printStackTrace(); 32 } catch (InstantiationException e) { 33 e.printStackTrace(); 34 } catch (InvocationTargetException e) { 35 e.printStackTrace(); 36 } 37 38 //调用静态无参方法 39 try { 40 Method sayStatic = c.getMethod("sayStatic"); 41 sayStatic.invoke(null); 42 } catch (NoSuchMethodException e) { 43 e.printStackTrace(); 44 } catch (InvocationTargetException e) { 45 e.printStackTrace(); 46 } catch (IllegalAccessException e) { 47 e.printStackTrace(); 48 } 49 50 //调用静态带参方法 51 try { 52 Method sayStatic2 = c.getMethod("sayStatic2", String.class); 53 sayStatic2.invoke(null,"Jerome"); 54 } catch (NoSuchMethodException e) { 55 e.printStackTrace(); 56 } catch (InvocationTargetException e) { 57 e.printStackTrace(); 58 } catch (IllegalAccessException e) { 59 e.printStackTrace(); 60 } 61 62 } 63 }
结果:
I am Jerome I am Man This is a static method This is a static method,I am Jerome
11. 获取到 Man 类所有的方法,及方法的修饰符,返回值和参数
1 public class ReflectTest1 { 2 public static void main(String[] args) { 3 Class<?> c = Man.class; 4 Method[] methods = c.getDeclaredMethods(); 5 for (Method method : methods) { 6 StringBuffer sb = new StringBuffer(); 7 //获取到方法的修饰符 8 String modifier = Modifier.toString(method.getModifiers()); 9 sb.append(modifier + " "); 10 Class<?> methodReturnType = method.getReturnType(); 11 //获取到方法的返回类型,没有返回值时为null 12 String returnType = methodReturnType.getName(); 13 String methodName = method.getName(); 14 if (returnType == null) { 15 sb.append("void "); 16 } else { 17 sb.append(returnType + " "); 18 } 19 sb.append(methodName).append("("); 20 Class<?>[] parameterTypes = method.getParameterTypes(); 21 for (Class parameter : parameterTypes) { 22 String name = parameter.getName(); 23 sb.append(name).append(","); 24 } 25 sb.append(")"); 26 System.out.println(sb.toString()); 27 } 28 } 29 }
结果:
public java.lang.String toString() public void sleep() public void say() private java.lang.String test1(java.lang.String,int,) public static void sayStatic() public void eat() public void sayName(java.lang.String,) public static void sayStatic2(java.lang.String,)
12. 获取到类加载器
1 public class ReflectTest2 { 2 public static void main(String[] args) { 3 Class<?> c = Man.class; 4 //获取到 classloader 5 ClassLoader classLoader = c.getClassLoader(); 6 //通过获取到classloader的类类型,得到classloader的名称 7 String name = classLoader.getClass().getName(); 8 System.out.println(name); 9 } 10 }
结果:
sun.misc.Launcher$AppClassLoader
13. 修改成员变量的值
1 public class ReflectTest3 { 2 public static void main(String[] args) { 3 Class<?> c = Man.class; 4 try { 5 Field name = c.getDeclaredField("name"); 6 name.setAccessible(true); 7 Object o = c.newInstance(); 8 name.set(o,"Haha"); 9 System.out.println(name.get(o)); 10 } catch (NoSuchFieldException e) { 11 e.printStackTrace(); 12 } catch (InstantiationException e) { 13 e.printStackTrace(); 14 } catch (IllegalAccessException e) { 15 e.printStackTrace(); 16 } 17 } 18 }
结果:
Haha
14. 获取数组相关信息
1 public class ReflectTest4 { 2 public static void main(String[ ] args){ 3 int[] temp = {1,2,4,5,7}; 4 Class<?> c = temp.getClass(); 5 Class<?> componentType = c.getComponentType(); 6 System.out.println("数组的类型:"+componentType.getName()); 7 System.out.println("数组的长度:"+Array.getLength(temp)); 8 System.out.println("数组第三个位置:"+Array.get(temp,2)); 9 Array.set(temp,2,44); 10 System.out.println("修改后的数组第三个位置:"+Array.get(temp,2)); 11 } 12 }
结果:
数组的类型:int 数组的长度:5 数组第三个位置:4 修改后的数组第三个位置:44