黑马程序员----反射
反射
---------------------- android培训、java培训、期待与您交流! ----------------------
一.Class类
java类用于描述一类是事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象确定的,不同的实例对象有不同的属性值。
1.得到各个字节码对应的实例对象
类名.class:Date.class
对象.getClass():new Date().getClass()
Class.forName("全类名"):Class.forName("java.util.Date");
----代码-----------------------------------------
Java代码
1.import java.util.*; 2.class ClassDemo 3.{ 4.public static void main(String[] args) 5.{ 6.try 7.{ 8.Date d = new Date(); 9.System.out.println(Date.class); 10.System.out.println(d.getClass()); 11.System.out.println(Class.forName("java.util.Date")); 12.} 13.catch (ClassNotFoundException cnfe) 14.{ 15.cnfe.printStackTrace(); 16.} 17.} 18.} 19.20./*运行结果: 21.class java.util.Date 22.class java.util.Date 23.class java.util.Date 24.*/ ----代码结束-------------------------------------1.class ReflectTest 2.{ 3.public static void main(String[] args) 4.{ 5.String s = "abc"; 6.Class cls1 = s.getClass(); 7.System.out.println("cls1对应的对象是基本数据类型吗? " + cls1.isPrimitive()); 8.System.out.println("int是基本书记类型吗? " + int.class.isPrimitive()); 9.System.out.println("int对应的字节码与Integer对应的字节码相等吗? " + (int.class == Integer.class)); 10.System.out.println("int 与 Integer 类型相等吗? " + (int.class == Integer.TYPE)); 11.System.out.println("int数组是基本数据类型吗?" + int[].class.isPrimitive()); 12.System.out.println("判断实例对象是否为数组使用方法为isArray() int[].class.isArray(): " + int[].class.isArray()); 13.} 14.} 15.16./*结果: 17.18.cls1对应的对象是基本数据类型吗? false 19.int是基本书记类型吗? true 20.int对应的字节码与Integer对应的字节码相等吗? false 21.int 与 Integer 类型相等吗? true 22.int数组是基本数据类型吗?false 23.判断实例对象是否为数组使用方法为isArray() int[].class.isArray(): true 24.25.*/ ----代码结束-------------------------------------1.import java.lang.reflect.*; 2.class ConstructorDemo 3.{ 4.public static void main(String[] args) 5.{ 6.try 7.{ 8.Constructor con = String.class.getConstructor(StringBuffer.class);//获得方法时用到的类型 9.String s = (String)con.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象 10.System.out.println(s.charAt(2)); 11.} 12.catch (Exception e) 13.{ 14.e.printStackTrace(); 15.} 16.} 17.} 18./*结果 19.e 20.*/ ----代码结束-------------------------------------1.import java.lang.reflect.*; 2.class RefiecPointDemo 3.{ 4.private int x; 5.public int y; 6.private int z; 7.private String s1; 8.private String s2; 9.private String s3; 10.public String s4; 11.public RefiecPointDemo(int x,int y,int z) 12.{ 13.this.x = x; 14.this.y = y; 15.this.z = z; 16.} 17.public RefiecPointDemo(int x,int y,int z,String s1,String s2,String s3,String s4) 18.{ 19.this.x = x; 20.this.y = y; 21.this.z = z; 22.this.s1 = s1; 23.this.s2 = s2; 24.this.s3 = s3; 25.this.s4 = s4; 26.} 27.} 28.class RefiecPoint 29.{ 30.public static void main(String[] args) 31.{ 32.try 33.{ 34.System.out.println("第一部分:"); 35.RefiecPointDemo rd = new RefiecPointDemo(2,7,13); 36.//要获得类中的成员变量,首先要获得该对象的字节码 37.Class c = rd.getClass(); 38.//获得字节码后获得y变量的对象 39.Field fY = c.getField("y"); 40.//得到对象后,获取值,还要指定是从那个对象中获取的 41.System.out.println(fY.get(rd)); 42.//以上只能获取访问修饰符为public的变量 43.//下面是获取所有访问修饰符的变量 44./* 45.获得字节码就要用到getDeclaredField()表示 46.的类或接口的以声明的字段 47.*/ 48.Field fX = c.getDeclaredField("x"); 49.//获得字节码后并不能直接使用,必须暴力获得访问权限 50.//用到的方法时Field父类AccessibleObject类中 51.//setAccessible(boolean flag)方法 52.fX.setAccessible(true); 53.//现在此对象才有访问权限 54.System.out.println(fX.get(rd)); 55.//----------------------------- 56.for (int i=0 ;i<2 ;i++ ) 57.System.out.println(); 58.System.out.println("第二部分"); 59./* 60.发现API中有Field[] getDeclaredFields()和Filed[] getFields[] 61.62. 63.try一try 64.*/ 65.//不知道有什么变量那肯定就不知道访问权限了,所以首选暴力的 66.Field[] fAll = c.getDeclaredFields(); 67.for(Field f : fAll) 68.{ 69.f.setAccessible(true); 70.System.out.println(f.getName() + "的值: " + f.get(rd)); 71.} 72.//OK 完全得到结果。 73.//---------------------- 74.for (int i=0 ;i<2 ;i++ ) 75.System.out.println(); 76.System.out.println("第三部分:"); 77.//把所有String类型的变量值“b”改为“a” 78.//创建需反射类对象 79.RefiecPointDemo rd1 = new RefiecPointDemo(3,5,7,"nbnbbaade","bfasbbe","fgrbdffbfbsdb","sdfesfe"); 80.//获得此对象字节码 81.Class c1 = rd1.getClass(); 82.//获取声明的所有变量 83.Field[] fAll1 = c1.getDeclaredFields(); 84.System.out.println("原始值:"); 85.//循环操作 86.for(Field f : fAll1) 87.{ 88.//修改权限 89.f.setAccessible(true); 90.//获得所有Sting类型 91.if(f.getType().getSimpleName().equals("String")) 92.{ 93.String temp = f.get(rd1).toString(); 94.System.out.println(f.getName() + "的值为:" + temp); 95.StringBuilder sb = new StringBuilder(); 96.for (int i=0;i < temp.length() ;i++ ) 97.{ 98.if(temp.charAt(i) == 'b') 99.{ 100.sb.append('a'); 101.continue; 102.} 103.sb.append(temp.charAt(i)); 104.} 105.f.set(rd1,sb.toString()); 106.//System.out.println(sb); 107.} 108.} 109.//修改后的值 110.System.out.println("修改后的值:"); 111.fAll1 = c1.getDeclaredFields(); 112.for(Field f : fAll1) 113.{ 114.f.setAccessible(true); 115.System.out.println(f.getName() + "的值: " + f.get(rd1)); 116.} 117.//------------------------------------------- 118.for (int i=0 ;i<2 ;i++ ) 119.System.out.println(); 120.System.out.println("第四部分:"); 121. 122. 123.RefiecPointDemo rd2 = new RefiecPointDemo(3,5,7,"nbnbbaade","bfasbbe","fgrbdffbfbsdb","sdfesfe"); 124.//获得此对象字节码 125.Class c2 = rd2.getClass(); 126.//获取声明的所有变量 127.Field[] fAll2 = c2.getDeclaredFields(); 128.System.out.println("原始值:"); 129.//循环操作 130.for(Field f : fAll2) 131.{ 132.//if(f.getType().getSimpleName().equals("String"))为什么非要转换成字符串呢?字节码也可以比较呀 133.//想到了要先获得类型看看是不是String,那么getType()返回的的是Class我们可以找到String.class去比较呀 134.if(f.getType() == String.class)//这里用==比用equals更加专业,返回的结果相同 135.{ 136./*用了这么多代码就是将字符串里某个字符换为另外一个字符,但Sting的API有现成的方法。悲哀 137.String temp = f.get(rd1).toString(); 138.System.out.println(temp); 139.StringBuilder sb = new StringBuilder(); 140.for (int i=0;i < temp.length() ;i++ ) 141.{ 142.if(temp.charAt(i) == 'b') 143.{ 144.sb.append('a'); 145.continue; 146.} 147.sb.append(temp.charAt(i)); 148.}*/ 149.//修改权限 150.f.setAccessible(true); 151.String oldString = f.get(rd2).toString(); 152.System.out.println(f.getName() + "的值为:" + oldString); 153.String newString = oldString.replace('a','b'); 154.f.set(rd2,newString); 155.} 156.} 157.//修改后的值 158.System.out.println("修改后的值:"); 159.fAll2 = c1.getDeclaredFields(); 160.for(Field f : fAll2) 161.{ 162.f.setAccessible(true); 163.System.out.println(f.getName() + "的值: " + f.get(rd1)); 164.} 165.} 166.catch (Exception e) 167.{ 168.e.printStackTrace(); 169.} 170.} 171.} 172.173./*结果: 174.第一部分: 175.7 176.2 177.178.179.第二部分 180.x的值: 2 181.y的值: 7 182.z的值: 13 183.s1的值: null 184.s2的值: null 185.s3的值: null 186.s4的值: null 187.188.189.第三部分: 190.原始值: 191.s1的值为:nbnbbaade 192.s2的值为:bfasbbe 193.s3的值为:fgrbdffbfbsdb 194.s4的值为:sdfesfe 195.修改后的值: 196.x的值: 3 197.y的值: 5 198.z的值: 7 199.s1的值: nanaaaade 200.s2的值: afasaae 201.s3的值: fgradffafasda 202.s4的值: sdfesfe 203.204.205.第四部分: 206.原始值: 207.s1的值为:nbnbbaade 208.s2的值为:bfasbbe 209.s3的值为:fgrbdffbfbsdb 210.s4的值为:sdfesfe 211.修改后的值: 212.x的值: 3 213.y的值: 5 214.z的值: 7 215.s1的值: nanaaaade 216.s2的值: afasaae 217.s3的值: fgradffafasda 218.s4的值: sdfesfe 219.*/ 1.import java.lang.reflect.*; 2.class MethodDemo 3.{ 4.public static void main(String[] args) 5.{ 6.MethodTest mt = new MethodTest(); 7.Method[] method = mt.getClass().getMethods(); 8.Method[] methods = mt.getClass().getDeclaredMethods(); 9.System.out.println("共有方法 " + method.length + " 个"); 10.//mt.getClass().getMethods();这个方法返回的是本类所有public方法及父类所有可访问方法 11.for(Method m : method) 12.{ 13.System.out.println("getName(): " + m.getName()); 14.} 15.System.out.println(); 16.//mt.getClass().getDeclaredMethods(); 访问的是本类中所有方法 17.18./*结果 分开写了!上面for打出来的的结果 19.20.共有方法 11 个 21.getName(): show1 //反射的类的public方法 22.getName(): show2 //反射的类的public方法 23.getName(): wait //父类Object可以访问的方法 24.getName(): wait //父类Object可以访问的方法 25.getName(): wait //父类Object可以访问的方法 26.getName(): equals //父类Object可以访问的方法 27.getName(): toString //父类Object可以访问的方法 28.getName(): hashCode //父类Object可以访问的方法 29.getName(): getClass //父类Object可以访问的方法 30.getName(): notify //父类Object可以访问的方法 31.getName(): notifyAll //父类Object可以访问的方法 32.33.*/ 34.System.out.println("共有方法 " + methods.length + " 个"); 35.for(Method m : methods) 36.{ 37.38.//m.setAccessible(true); 39.System.out.println("getName(): " + m.getName());//以 String 形式返回此 Method 对象表示的方法名称。无需设置权限或说暴力破解也可获得私有方法 40.System.out.println("getGenericReturnType() : " + m.getGenericReturnType());//返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。 41.System.out.println("getModifiers(): " + m.getModifiers());//以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符 42.System.out.println("getParameterTypes(): " + m.getParameterTypes().length);//按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。 43.System.out.println("getReturnType(): " + m.getReturnType());//返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。 44.System.out.println("isSynthetic() : " + m.isSynthetic());//如果此方法为复合方法,则返回 true;否则,返回 false。\ 45.System.out.println("isVarArgs(): " + m.isVarArgs());//如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。 46.System.out.println("toGenericString(): " + m.toGenericString());//返回描述此 Method 的字符串,包括类型参数。 47.System.out.println(); 48.System.out.println("-----华丽的分割线登场-------"); 49.System.out.println(); 50.51./*结果: 52.共有方法 5 个 53.getName(): show1 54.getGenericReturnType() : void 55.getModifiers(): 9 56.getParameterTypes(): 0 57.getReturnType(): void 58.isSynthetic() : false 59.isVarArgs(): false 60.toGenericString(): public static void MethodTest.show1() 61.62.--------------- 63.64.getName(): show2 65.getGenericReturnType() : int 66.getModifiers(): 1 67.getParameterTypes(): 0 68.getReturnType(): int 69.isSynthetic() : false 70.isVarArgs(): false 71.toGenericString(): public int MethodTest.show2() 72.73.--------------- 74.75.getName(): show3 76.getGenericReturnType() : class java.lang.String 77.getModifiers(): 8 78.getParameterTypes(): 0 79.getReturnType(): class java.lang.String 80.isSynthetic() : false 81.isVarArgs(): false 82.toGenericString(): static java.lang.String MethodTest.show3() 83.84.---------------- 85.86.getName(): show4 87.getGenericReturnType() : void 88.getModifiers(): 10 89.getParameterTypes(): 0 90.getReturnType(): void 91.isSynthetic() : false 92.isVarArgs(): false 93.toGenericString(): private static void MethodTest.show4() 94.95.--------------- 96.97.getName(): show5 98.getGenericReturnType() : class java.lang.String 99.getModifiers(): 128 100.getParameterTypes(): 2 101.getReturnType(): class java.lang.String 102.isSynthetic() : false 103.isVarArgs(): true 104.toGenericString(): java.lang.String MethodTest.show5(int,int[]) 105.106.//--------------- 107.108.*/ 109.} 110.} 111.} 112.class MethodTest 113.{ 114.public static void show1() 115.{ 116.int i = 0; 117.String s = "s"; 118.System.out.println("public static void show()"); 119.} 120.public int show2() 121.{ 122.int i = 0; 123.String s = "s"; 124.System.out.println("public void show2()"); 125.return i; 126.} 127.static String show3() 128.{ 129.int i = 0; 130.String s = "s"; 131.System.out.println("static void show3()"); 132.return s; 133.} 134.private static void show4() 135.{ 136.int i = 0; 137.String s = "s"; 138.System.out.println("private static void show4()"); 139.} 140.String show5(int a,int ... b) 141.{ 142.String s = "s"; 143.System.out.println("String show5()"); 144.return s; 145.} 146.}