A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 龚振 龚振 龚振 中级黑马   /  2012-4-18 18:03  /  2989 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

for(Field field : fields){
if(field.getType()==java.lang.String.class)
这里用==比equals好,张老师说字节码都是那一份,我没听懂。
谁能通俗点解释清楚下么?

2 个回复

倒序浏览
一。。字节码:当要调用到类时首先是将类的字节码加载到硬盘中
得到一个类的字节码:
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);
希望对你有帮助
回复 使用道具 举报
本帖最后由 黑马我来了 于 2012-4-18 18:38 编辑

  equals是比较两个对象的内容,field.getType()和java.lang.String.class都是内存中的字节码,==操作是比较变量的值是否相等,对于引用变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马