java笔记-高新技术-反射
2014-08-19 15:47
459 查看
反射的基石-Class类
反射就是把java类中的各种成分映射成相应的java类,java反射机制就是在运行状态中,对于任意个类,都能够知道这个类 的所有属性和方法;对于任意一个对象,都能够调
它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能称之为java语言的反射机制。
该机制允许程序通过Reflect APIs取得任何已知名称的class的内部信息,例如modifiers(public ,private),superclass(object),interface(Cloneable),也包括基本数据类型,
机制可于运行时改变fields内容和methods。
关于动态语言:一般认为,程序在运行时,可改变程序的结构或者变量类型的语言。
java因有了Reflect,使其具有动态语言的特性,我么可以在程序运行时,加载使用编译期间完全位置的classes,即java可以加载在运行时才得知名称的class并获得其完整构造,生成对象实体,设置field,访问method。这种看透class的能力被称为Introspection(内省)。
Class的产生:当一个类被加载或被jvm调用,jvm会自动产生一个Class object。由于Class的构造方法是私有的,所以不能通过自定义对象的方式产
java反射机制的主要功能:
1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法;
4.在运行时调用任意一个对象的方法;
5.生成动态代理。
字节码:当类被加载到内存中,占用内存中的一片空间,该空间里面的内容就是类的字节码,不同类的字节码是不同的。
获取字段值:
框架与工具类有区别:工具类被用户的类调用;而框架则调用用户提供的类。
用户要用框架,则框架如何调用随后用户书写的类,此时需要用到反射。
javabean实例
javabean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有 的字段,如果要在两个模块间传递多个信息,可将该信息封装到javabean中,这些信息在类中用私有字段来存储。javabean的属性是根据方法名来判断出来的,一般如getName去掉get,Name即是属性名。jdk中提供了对javabean操作的api,这套api称为内省,用内省来访问私有化的成员和变量非常方便。
反射就是把java类中的各种成分映射成相应的java类,java反射机制就是在运行状态中,对于任意个类,都能够知道这个类 的所有属性和方法;对于任意一个对象,都能够调
它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能称之为java语言的反射机制。
该机制允许程序通过Reflect APIs取得任何已知名称的class的内部信息,例如modifiers(public ,private),superclass(object),interface(Cloneable),也包括基本数据类型,
机制可于运行时改变fields内容和methods。
关于动态语言:一般认为,程序在运行时,可改变程序的结构或者变量类型的语言。
java因有了Reflect,使其具有动态语言的特性,我么可以在程序运行时,加载使用编译期间完全位置的classes,即java可以加载在运行时才得知名称的class并获得其完整构造,生成对象实体,设置field,访问method。这种看透class的能力被称为Introspection(内省)。
Class的产生:当一个类被加载或被jvm调用,jvm会自动产生一个Class object。由于Class的构造方法是私有的,所以不能通过自定义对象的方式产
Class object 诞生管道 | 示例 |
运用getClass() 注:每个class 都有此函数 | String str = "abc"; Class c1 = str.getClass(); |
运用 Class.getSuperclass()2 | Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass(); |
运用static method Class.forName() (最常被使用) | Class c1 = Class.forName ("java.lang.String"); Class c2 = Class.forName ("java.awt.Button"); Class c3 = Class.forName ("java.util.LinkedList$Entry"); Class c4 = Class.forName ("I"); Class c5 = Class.forName ("[I"); |
运用 .class 语法 | Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; |
运用 primitive wrapper classes 的TYPE 语法 | Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE; |
1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法;
4.在运行时调用任意一个对象的方法;
5.生成动态代理。
字节码:当类被加载到内存中,占用内存中的一片空间,该空间里面的内容就是类的字节码,不同类的字节码是不同的。
获取字段值:
package net.csing; import java.lang.reflect.*; public class FieldDemo { /** * @param args */ public static void main(String[] args){ //创建要操作的对象。 ReflectPoint rf=new ReflectPoint(2,3); try{ /* * 获取public字段的值。 */ Field fx=rf.getClass().getField("x"); //获取字段fx所对应的在某对象rf上的值 System.out.println("x:"+fx.get(rf)); /* * 获取private字段的值。 */ Field fy=rf.getClass().getDeclaredField("y"); fy.setAccessible(true); //获取字段f所对应的在某对象rf上的值 System.out.println("y:"+fy.get(rf)); } catch(Exception e){ throw new RuntimeException("error."); } } } class ReflectPoint{ public int x; private int y; public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } }字段遍历及字符替换
package net.csing; import java.lang.reflect.*; public class FieldDemo { /** * @param args */ public static void main(String[] args){ //创建要操作的对象。 ReflectPoint rf=new ReflectPoint(2,3); try{ /* * 获取public字段的值。 */ Field fx=rf.getClass().getField("x"); //获取字段fx所对应的在某对象rf上的值 System.out.println("x:"+fx.get(rf)); /* * 获取private字段的值。 */ Field fy=rf.getClass().getDeclaredField("y"); fy.setAccessible(true); //获取字段f所对应的在某对象rf上的值 System.out.println("y:"+fy.get(rf)); /* * 将对象对应的字段中的含有b的字符串全部替换成a */ changeStringChar(rf); //打印结果 System.out.println(rf); } catch(Exception e){ throw new RuntimeException("error."); } } private static void changeStringChar(ReflectPoint rf) { /* * 获取对像对应的所有字段。 */ Field[] field=rf.getClass().getFields(); try{ //遍历字段。 for(Field f:field ){ //筛选string字段。 if(f.getType()==String.class){ //获得字段对应的值。 String oldStr=(String)f.get(rf); //将b替换为a String newStr=oldStr.replace('b', 'a'); //将替换后的结果写入对象。 f.set(rf,newStr); } } } catch(Exception e){ throw new RuntimeException("error."); } } } //操作字段的反射类。 class ReflectPoint{ public int x; private int y; public String str1="abcdefg"; public String str2="abcdefgijkla"; public String str3="efg"; //初始化x,y public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } //重写该类对应的toString方法。 public String toString(){ return str1+":"+str2+":"+str3; } }反射的作用:实现框架功能
框架与工具类有区别:工具类被用户的类调用;而框架则调用用户提供的类。
用户要用框架,则框架如何调用随后用户书写的类,此时需要用到反射。
javabean实例
javabean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有 的字段,如果要在两个模块间传递多个信息,可将该信息封装到javabean中,这些信息在类中用私有字段来存储。javabean的属性是根据方法名来判断出来的,一般如getName去掉get,Name即是属性名。jdk中提供了对javabean操作的api,这套api称为内省,用内省来访问私有化的成员和变量非常方便。
package csing.net; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class IntroSpectionDemo { /** * @param args * @throws IntrospectionException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static void main(String[] args) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ReflectDemo rd=new ReflectDemo(6,9); String propertyName="x"; /* * PropertyDescriptor:描述javabean中propertyName的属性。 */ //获得属性对象。 PropertyDescriptor pd=new PropertyDescriptor(propertyName,rd.getClass()); //获得propertyName对应的方法。 Method methodGetX=pd.getReadMethod(); try { //使用方法获取X的值。 Object retVal=methodGetX.invoke(rd); System.out.println(retVal); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } /* * 获取设置属性的方法。 */ Method methodSetX=pd.getWriteMethod(); //方法引用。 methodSetX.invoke(rd, 19); //获取方法,取得值。 int retVal2=rd.getX(); System.out.println(retVal2); //通过beanInfo可获得对象对应的属性,方法等。 BeanInfo bi=Introspector.getBeanInfo(rd.getClass()); //根据对象获得Class //获得属性集 PropertyDescriptor[] pd2=bi.getPropertyDescriptors(); //遍历属性集 for(PropertyDescriptor p:pd2){ System.out.println("get read method:"); if(p.getName().equals(propertyName)){ //获得特定的属性。 System.out.println("I got his name:"+p.getName()); } //获得对象的get方法。 Method m=p.getReadMethod(); Object get_x=m.invoke(rd); System.out.println(get_x); } } } //反射测试类。 class ReflectDemo{ public ReflectDemo(int x, int y) { super(); this.x = x; this.y = y; } private int x=0; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } private int y=0; }
相关文章推荐
- Java反射及AOP笔记 (Java高新技术)
- Java高新技术笔记:反射、多线程、泛型、枚举、javaBean、代理
- 黑马程序员——Java高新技术视频笔记:反射
- Java高新技术视频笔记:反射
- 张孝祥Java高新技术_课程--------学习笔记第一天
- Java高新技术之框架的概念及用反射技术开发框架的原理和配置文件
- Java反射笔记4—Main方法反射
- Java的反射机制学习笔记
- java 之 反射笔记(二)
- Java高新技术之反射
- Java反射笔记2—构造器
- Java反射笔记1
- 黑马程序员_java学习日记_Java高新技术_反射(一)
- java反射学习笔记三(改进笔记二放到配置文件中)
- 学习笔记14—Java高新技术2
- 学习笔记13—Java高新技术1
- Java反射笔记3—变量和方法
- java反射学习笔记二
- java反射学习笔记一(解析java.lang.String)
- 黑马程序员—JAVA高新技术视频笔记