---------------------- <a target="blank">ASP.Net+Android+IO开发S</a>、<a target="blank">.Net培训</a>、期待与您交流! ----------------------
反射
- package cn.itcast.day1;
- public class ReflectTest {
- /**
- * @param args
- */
- public static void main(String[] args)throws Exception {
- // TODO Auto-generated method stub
- String str1 = "abc";
- Class cla1 = str1.getClass();
- Class cla2 = String.class;
- Class cla3 = Class.forName("java.lang.String");
- //验证三种方法是不是同一份字节码,答案都是true
- System.out.println(cla1==cla2);
- System.out.println(cla1==cla3);
- System.out.println(cla1.isPrimitive());//判断是否是一个基本数据类型
- System.out.println(int.class==Integer.class);//int和Integer是不同类型,各自有自己的字节码
- System.out.println(int.class==Integer.TYPE);//TYPE用来表示所包装的那份基本类型的字节码
- //数组出现的类型也有自己的字节码,用isArray()判断
- System.out.println(int[].class.isPrimitive());
- System.out.println(int[].class.isArray());
- }
- }
反射概念:就是把JAVA类中的各种成分映射成相应的JAVA类。
Constructor类:
1、概述:Constructor代表某个类的构造方法。
2、获取构造方法:
1、如何得到某个类的所有构造方法(如得到String类的所有构造方法):
Constructor[] cons = Class.forName(“java.lang.String”).getConstructors();
2、获取某一个构造方法:
Constructor con =String.class.getConstructor(StringBuffer.class); ①
3、创建实例对象:
1、通常方式:String str = new String(new StringBuffer (”abc”));
2、反射方式:String str = (String)con.newInstance(new StringBuffer(“abc”)); ②
调用获得的方法时要用到上面相同类型的实例对象,即两个StringBuffer()要对应相等。
NewInstance():构造出一个实例对象,每调用一次就构造一个对象。
注意:上面的两个地方①②都要用到StringBuffer,这必须是一致的。
第①个是指定要带StringBuffer参数类型的构造方法,即所需使用的是含StringBuffer类型的构造方法。
第②个是用这个构造方法创建对象,要传入的参数类型必须是StringBuffer。
Field类:
如:
- public class ReflectPoint {
- private int x;
- public int y;
- public String toString(){
- return str1+";" + str2 + ";" + str3;
- }
- }
- public class FieldTest(){
- ReflectPoint pt1 = new ReflectPoint(3,5);
- //fieldX和fieldY并不是对象身上的变量,而是类上的
- //要用它去取某个对象上的对应的值,传入什么对象,就取相应对象的值。
- Field fieldY = pt1.getClass().getField("y");
- System.out.println(fieldY.get(pt1));
- //获取私有的成员变量
- Field fieldX = pt1.getClass().getDeclaredField("x");
- fieldX.setAccessible(true);
- System.out.println(fieldX.get(pt1));
- }
Method类:
1、概述:Method类代表某个类中的一个成员方法。调用某个对象身上的方法,要先得到方法,再针对某个对象调用。
2、专家模式:谁调用这个数据,就是谁在调用它的专家。
如人关门。调用者:是门调用管的动作,对象是门,因为门知道如何执行关的动作,通过门轴之类的细节实现。指挥者:是人在指挥门做 关的动作,只是给门发出了关的信号,让门执行。
总结:变量使用方法,是方法本身知道如何实现执行的过程,也就是“方法对象”调用方法,才执行了方法的每个细节的。
3、获取某个类中的某个方法:(如String str = ”abc”)
1、通常方式:str.charAt(1)
2、反射方式:
Method charAtMethod = Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
charAtMethod.invoke(str,1);
说明:如果传递给Method对象的invoke()方法的第一个参数为null,说明Method对象对应的是一个静态方法
4、用反射方式执行某个main方法:
首先要明确为何要用反射:在写源程序时,并不知道使用者传入的类名是什么,但是虽然传入的类名不知道,而知道的是这个类中 的方法有main这个方法,所以可以通过反射的方式,通过使用者传入的类名(可定义字符串型变量作为传入类名的入口,通过这个 变量代表类名),内部通过传入的类名获取其main方法,然后执行相应的内容。
如:- //Method类演示
- private static void methodTest(String [] args) throws Exception {
- String str1 = "abc";
- //一般方法:
- System.out.println(str1.charAt(1));
- //反射方法 :
- Method methodCharAt =
- Class.forName("java.lang.String").getMethod("charAt",int.class);
- System.out.println(methodCharAt.invoke(str1,1));
- //用反射方式执行某个main方法
- //一般方式:
- Test.main(new String[]{"111","222","333"});
- System.out.println("-------");
- //反射方式:
- String startingClassName = args[0];
- Method methodMain =
- Class.forName(startingClassName).getMethod("main",String[].class);
- //方案一:强制转换为超类Object,不用拆包
- methodMain.invoke(null,(Object)new String[]{"111","222","333"});
- //方案二:将数组打包,编译器拆包后就是一个String[]类型的整体
- methodMain.invoke(null,new Object[]{new String[]{"111","222","333"}});
- }
- //定义一个测试类
- class Test{
- public static void main(String [] args){
- for(String arg : args){
- System.out.println(arg);
- }
- }
- }
数组的反射: