java reflect反射
TestClass类
1 package Reflect; 2 3 public class TestClass { 4 public TestClass(){} 5 public TestClass(int i){ 6 this.iTest = i; 7 } 8 9 private int iTest = 100; 10 11 public int getiTest() { 12 return iTest; 13 } 14 15 public void setiTest(int iTest) { 16 this.iTest = iTest; 17 } 18 }
1.获得class name的三种方法
1 package Reflect; 2 3 public class Main { 4 public static void main(String []args) { 5 Class<?> c1 = null; 6 Class<?> c2 = null; 7 Class<?> c3 = null; 8 9 try { 10 c1 = Class.forName("Reflect.TestClass"); 11 } catch (ClassNotFoundException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 16 c2 = new TestClass().getClass(); 17 c3 = TestClass.class; 18 19 System.out.println("C1="+c1.getName());//输出C1=Reflect.TestClass 20 System.out.println("C2="+c2.getName());//输出C2=Reflect.TestClass 21 System.out.println("C3="+c3.getName());//输出C3=Reflect.TestClass 22 23 } 24 }
2.通过Class.NewInstance()创建新的类示例
1 package Reflect; 2 3 public class Main { 4 public static void main(String []args) { 5 Class<?> c1 = null; 6 7 try { 8 c1 = Class.forName("Reflect.TestClass");//要点1:这里只是对类的加载和连接 9 } catch (ClassNotFoundException e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 } 13 14 TestClass tc = null; 15 try { 16 tc = (TestClass) c1.newInstance();//要点2:到这里才是类的实例化,之前只是加载和连接;要点3:newInstance调用的是非私有的无参构造函数 17 } catch (InstantiationException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } catch (IllegalAccessException e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 25 System.out.println(tc.getiTest()); 26 } 27 }
3.通过Constructor.newInstance()创建新的类示例
将TestClass里添加带参数的构造函数并设置为私有
1 private TestClass(int i){ 2 this.iTest = i; 3 } 4 5 private TestClass(int i,int useless){ 6 this.iTest = i; 7 }
1 package Reflect; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.InvocationTargetException; 5 6 public class Main { 7 public static void main(String []args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 8 Class<?> c1 = null; 9 10 try { 11 c1 = Class.forName("Reflect.TestClass");//要点1:这里只是对类的加载和连接 12 } catch (ClassNotFoundException e) { 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 17 Constructor<?> cc0 = c1.getDeclaredConstructor(); 18 cc0.setAccessible(true); 19 TestClass tcc0 = (TestClass)cc0.newInstance(); 20 System.out.println(tcc0.getiTest()); 21 //调用私有的构造函数 22 Constructor<?> cc1 = c1.getDeclaredConstructor(int.class); 23 cc1.setAccessible(true); 24 TestClass tcc1 = (TestClass)cc1.newInstance(10); 25 System.out.println(tcc1.getiTest()); 26 27 //调用私有的多参数构造函数 28 Constructor<?> cc2 = c1.getDeclaredConstructor(int.class,int.class); 29 cc2.setAccessible(true); 30 TestClass tcc2 = (TestClass)cc2.newInstance(20,0); 31 System.out.println(tcc2.getiTest()); 32 } 33 }
4.修改私有函数和私有变量
将setiTest设置为私有
1 private void setiTest(int iTest) { 2 this.iTest = iTest; 3 }
1 package Reflect; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 7 public class Main { 8 public static void main(String []args) { 9 Class<TestClass> clazz = TestClass.class; 10 TestClass tc; 11 try { 12 tc = clazz.newInstance(); 13 //调用私有方法 14 Method method = clazz.getDeclaredMethod("setiTest", int.class);//函数名,参数/参数数组 15 method.setAccessible(true);//设置不进行访问检查 16 method.invoke(tc, 123); //实例, 参数值 17 System.out.println(tc.getiTest()); 18 19 //修改私有变量的值 20 Field field = clazz.getDeclaredField("iTest");//变量名 21 field.setAccessible(true);//设置不进行访问检查 22 field.set(tc, 12345);//实例,要修改的值 23 System.out.println(tc.getiTest()); 24 } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException | NoSuchFieldException e) { 25 // TODO Auto-generated catch block 26 e.printStackTrace(); 27 } 28 } 29 }