------- android培训、java培训、期待与您交流! ----------
反射
反射会消耗性能
反射就是把Java类中的各种成分映射成相应的java类
例如:一个Java类中用一个Class类的对象来表示
一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个Java类来表示
就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类
表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,包等信息
这些信息就是用相应的实例对象来表示
它们是Field(变量) Method(方法) Contructor(构造方法) Packet(包)等等
Constructor类
Constructor类代表某个类中的一个构造方法
得到某个类所有的构造方法
例子: Constructor[] con = Class.forName(java.lang.String").getConstructors();
得到某一个构造方法
例子: Constructor con = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
StringBuffer是传入构造方法的参数类型,用来确定到底获得哪个构造方法Constructor con = Class.forName("java.lang.String").getConstructor(StringBuffer.class,int.class);
代表得到的构造方法是传入StringBuffer和int参数的构造方法
//获得方法时要用到类型
创建实例对象:
通常方式: String str = new String (new StringBuffer("abc"));
反射方式: String str = (String)con.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象
Class.newInstance()方法
例子: String obj = (String)Class.forName("java.util.lang").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法来创建实例 对象
该方法内部的具体代码是怎样写的呢?
用到了缓存机制来保存默认构造方法的实例对象
File类
File类代表某个类中的一个成员变量
演示用eclipse自动生成Java类的构造方法
问题:得到的File对象是对应到类上面的成员变量,还是对应到对象上面的成员变量?
(答: 对应到类上面的成员变量)类只有一个,而该类的实例对象有多个,如果是与对象关联,那关联的是哪个对象呢?
所以用字段fileX代表的是x的定义,而不是具体的x变量
实例代码:
ReflectPoint p = new ReflectPoint(1,7);
File y = Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");
System.out.println(y.get(p));
File x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");//因为x是私有的,不可见,所以要调用getDeclaredField()方法,获取只要定义过的成员变量,不管私有还是公有
x.setAccessible(true);//因为x是私有的,可以看见了,但不可以访问,setAccessible的值为true时,就代表着反射的对象在使用时,取消访问限制,这叫暴力反射
System.out.println(x.get(p));
作业:将任意一个对象的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
Method类
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt".int.class);调用方法:
通常方式: System.out.println(str.charAt(1));
反射方式: System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?
说明该Method对象对应的是一个静态方法
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5: public Object invoke(Object obj,Object...args)
jdk1.4: public Object invoke(Object obj,Object[] args)
即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数
所以,调用charAt方法的代码也可以用jdk1.4改写为
charAt.invoke("str",new Object[]{1})形式