JavaSE学习笔记--反射

 

反射 (Reflect):就是把java类中的各种成分映射成相应的java类。
使用的步骤都是一样,均先得到该类的Class字节码文件,再得到相应的字段或方法。
Package 类 :略
Method 类 :
  //还是以String类中的charAt()方法为例
  String str1 ="abc";
  Method methodCharAt = String.class.getMethod("charAt",int.class);
  methodCharAt.invoke(str1,1); //其中"1",若是按1.4的语法调用改为 new Object[]{1}

 main()方法反射:
  特殊知识点:
   当使用反射来执行另外一个类中的main方法。由于Jdk1.5要兼容Jdk1.4,new String[]{"xxxx"}会当作多个参数处理,
  而不能做一个数组作为一个整体,此时的参数有两种如下的处理方法:
   1,mainMethod(null,new Object[](new String[]{"xxxx"}));
   2,mainMethod(null,(Object)new String[]{"xxxx"});
   代码如下:
   String startingClassName = args[0];//运行之前还需在编译器中将"类的完整名称"设置到参数列表。
   Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
   mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
   /*或*/mainMethod.invoke(null, (Objcet){new String[]{"111","222","333"}});//建议使用这种方法,效率较高。
   
   
 数组的反射:
   只有当数组的类型和纬度相同,这两个数组的字节码文件才可以相等。(长度可以不相等)
   Arrays.asList()方法处理int[]和String[]时的差异。int不是Object的类型[* int[] 是Object类型 ],所以jdk1.4的方法Arrays.asList(Object[] obj)是不适用的,
   只能按jdk1.5的走,把int[]作为一个Object,就打印出了这种效果[[I@1cfb549]

Field 类 :
 方法:getFields(); getField(); getDeclaredField();/*注意需要暴力反射*/
 代码:
  Person p1 = new Person(3,5);
  Field fieldY = P1.getClass().getField("y");
  //fieldY的值是多少?是5,错。fieldY 不是对象身上的变量,而是类上的,要用它去取某个对象的值。
  System.out.println(fieldY.get(p1));
  /*
  //注意若Y字段是private的话,就得使用getDeclaredField(); 还有就是暴力反射
  Field fieldY = P1.getClass().getDeclaredField("y");
  fieldY.setAccessible(true);    //暴力反射
  System.out.println(fieldY.get(p1));
  */
Constructor 类 :  
   方法:getConstructors(); getConstructor();
   代码:
  //new String(new StringBuffer("abc"));以下以String类为例
  
  Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
  String str1 = (String)constructor1.newInstance(new StringBuffer("abc"));  //注意要和上边的类型统一,都是StringBuffer
  //验证一下,打印Str1的第三个字符
  System.out.println(str1.charAt(2));


扩展:字段之间的比较要用“=”更合适。

使用Beanutils工具包来设置java类的属性:
使用前需要导入Beanutils工具包 和 Logging包。
 ReflectPoint pt1 =new ReflectPoint(3,5);
 BeanUtils.setProperty(pt1,"x","9"); //注意使用时x当作String类型的,而不是int
 System.out.println(pt1.getX());
 又如:(支持属性的"级延操作")
 BeanUtils.setProperty(pt1,"birthday.time","111");birthday是一个复合属性,他下边还有一个time,因为birthday有一个setTime()方法。
 System.out.println(BeanUtils.getProperty(pt1,"birthday.time"));birthday是一个复合属性,他下边还有一个time,因为birthday有一个setTime()方法。

使用PropertyUtils.setProperty(pt1,"x",9);
System.out.println(PropertyUtils.getProperty(pt1,"x").getClass()); //注意使用时x当作Int类型的,String.(与BeanUtils类不同)

框架和反射原理:
 FileInputStream fis = new FileInputStream("conf.properties");
 Properties properites = new Properties();
 properties.load(fis);
 fis.close();

 String className = properties.getProperty("className");
 Collection col = (Collection)Class.forName(className).newInstance();
 理解(安装门):框架好比房子,锁好比工具类,门就是自己编写的类。房子提前做好了,房子调用门,门调用锁。
     框架调用我自己写的类,我调用工具类来组成门。
类加载器:
 InputStream ips = Person.class.getClassLoader().getResourceAsStream("cn/itcast/day01/conf.properties");
或  InputStream ips = Person.class.getResourceAsStream("conf.properties"); //这个是相对于Person.class所在的包而言的。

 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭