一。。字节码:当要调用到类时首先是将类的字节码加载到硬盘中
得到一个类的字节码:
forName的作用:返回字节码
二。。两种返回字节码的方法
1.被加载过 在java虚拟机里。。直接返回
2.没有被加载过。没有在java虚拟机里。类加载器加载 吧加载过的字节码 放到虚拟机中,以后就不用
在加载了
在反射时用:class。forName("类名");
三。。 反射:
A:概念
就是吧java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class类的对象来表示,
一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用到一个个的java类来表示,就像汽
车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列
的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息,method。Contructor.Package等等
一个类中的每个成员都可以用相应的反射API 类的一个实例对象来表示,通过调用Class类的方法可以
得到这些实例对象后,得到这些实例对象
method代表字节码的方法
Constructor代表某个类(字节码)中的一个构造方法
字节码的getConstructor 的方法
通过构造方法可以得到一下内容:
1.自己的类、2.得到修饰符 (private public ) 3.newInstance(最重要的方法)
字节码对象的newInstance方法
eg:
Constructor cons=String.class.getConstructor(StringBuffer.class);
String str2=(String)cons.newInstance(new StringBuffer("abc"));//编译时只看变量的定义
不管变量的赋值。所以需要cons 并不知道自己是一个String 类。所以要强转为String类
//getConstructor 和 newInstance 中的参数类型必须一致
getConstructor传入一个类型。调用获得方法时传入的时同样类型的对象
B:性能
反射消耗性能 是性能大大下降 所以需要将得到的无参构造方法缓存起来 下次调用是直接调用缓存
好的 构造方法
C:成员变量的反射:
涉及到的类--》Filed类 .Filed 类代表的是字节码中的成员变量 不代表对象的变量
“得到的Field对象是对应到该类上面的成员变量,还是对应到对象的 成员变量?类只有一个,二该
类的实例化对象有多个,如果是与对象关联,那关联的是哪个对象呢?所以字段fdx代表的是x的定义,
二不是具体的x变量” 这是张老师的原话。。看下边的例子 帮助你理解:
所以通过filed对象的get方法传入一个类的对象
语法:类 pt=new 类(a,b);//实例化类 并传入两个参数
Field fdx=pt.getClass().getFiled("参数")//参数是类中的一个属性名,也就是得到指定属
性的值反射到 该类中
fd.get(pt); //fd 并不是一个对象上的变量。而是类上的,要用他去取对应(由参数参数)
对象的值
主:此时getFiled();方法得到的时可见的方法,也就是公开的变量 。
当该参数是私有时,以上方法则不可用fd的getfd()则不可用,
fd.setAccessible(ture);可以访问私有的变量.这是暴力访问
D:字节码比较时用:==:因为同一份字节码。。最好不用equals
字符替换一例::::
eg。Filed fields=obj.getClass().getFields();
for(Field field:fields){
if(field.getType()==String.class){//如果得到的类型码是string类型码
String oldVal=(String)filed.get(pt);// pt是上个类中的对象(做为参数传入即可)
String newVal=oldVal.replace('b','a')//把a替换成b(get一下)
filed.set(pt,newVal);//然后吧pt中的字符设置成新字符(set一下)
}
}
总结:反射成员变量的步骤--->
1.声明一个要获得类中成员变量的实例对像
类名 实例名=new 类名();
2.获得该类的filed对象,用于下面获得其中的数据
静态成员变量要用到getDeclaredFiled();
Filed filed=实例名.getClass().getFiled("类成员变量名");
3.获得该成员的数据
String oldVal=filed.get(类的实例名);
当该成员变量是静态的要设置Filed实例的获取权限 setAccessible();
filed.setAccessible(true);
4.新值替换旧值
String newVal =old.replace('b','a');//把a替换成b
filed.get(类的实例名,newVal);
希望对你有帮助 |