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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孔肖 中级黑马   /  2012-9-23 16:19  /  1908 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孔肖 于 2012-9-23 18:01 编辑

这个方法是将任意对象中的所有String字段中的'b'-->'B'
疑惑的地方用红色标出了,请各位能讲的简单详细深入一点!谢谢!

public static void changeStringValue(Object obj) throws Exception
{
         Field[] fields = obj.getClass().getFields();
  
        for(Field field : fields)
       {   
             // 张老师说这里是同一份字节码,我的疑惑是获取到的字节码和String类的字节码在内存中时如何存放的,对于 "=="的比较又是如何比较的?
             if(field.getType() == String.class)
            {
                  // 这里要注意类型转换 obj --> String,上面已经比较了类型,为什么这里还要类型转换?
                  String oldValue = (String)field.get(obj);
                  String newValue = oldValue.replace('b', 'B');
                 field.set(obj, newValue);
             }
      }
}

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
field.getType() == String.class  这句话的意思就是判断你所获取的是不是String类型的,因为一个类中的字段可能有很多,至于用==号就是因为字符串属于常量池中的元素。 所以不用equals。。用equals方法也能通过,但是==会显得更专业点

String oldValue = (String)field.get(obj); filed的get()方法返回值就是Object类型的,他得到指定对象上的字段还不能够确定,也有可能int等 都不一样的
所以,要进行强转

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

回复 使用道具 举报
一个类首先要被Java虚拟机装载到内存里面才能使用,String类也不例外。Java虚拟机将String.class文件从硬盘读取到内存里面,经过一系列处理后就变成了字节码。要注意的是,任何一种数据类型(例如String、int)所对应的Class实例对象在内存里面只保存一份,也就是说无论我们以什么样的形式获取Class实例对象,只要是它们所对应的数据类型相同,那它们的引用地址也相同。举个例子:
  1. Class clazz1 = String.class;
  2. Class clazz2 = new String("").getClass();
复制代码
以上两种获取Class实例对象clazz的方法很不相同,但是它们最终获取到的Class实例其实是同一个,也就是clazz1和clazz2都指向内存里面同一份字节码,就是因为无论是clazz1还是clazz2,它们的字节码所对应的数据类型都是String类型。
因此,你的问题中,if语句的判定条件的意思就是当field.getType()的返回结果是String.class时(“==”就是比较两个对象的引用是否相等,说白了就是看两个对象是否是同一个),也就是说field里面封装的数据的真实类型是String类型时,就执行if语句。
之所以要在下面进行强制类型转换,是因为替换字符的方法replace()是String类所拥有的,field.get(obj)返回的是Object类型的数据,不含replace方法,而编译器在编译阶段是无法确定field.get(obj)返回值的真实类型的,因此需要用强制转换告诉编译器field.get(obj)所返回的对象是就是String类型的,好让编译器通过,而我们也就可以在后面使用replace()方法了

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
equals比较的是让内容是否相同 而==表示是否指向同一个对象
回复 使用道具 举报
本帖最后由 陈德基 于 2012-9-23 17:33 编辑

反射。就是将java类中的各个成分(class类的实例对象)映射到相应的java类上,这个是张老师视频里的引用,加了点我自己的理解,

getClass();通过这个方法能得到该类在内存中的字节码(已经在内存中,是唯一的)。

举个例子:
String str1 = "abc";

Class cls1 = str1.getClass();

Class cls2 = String.class;

Class cls3 = Class.forName("java.lang.String");

sop(cls1 == cls2);  true
sop(cls1 == cls3);  true
上面两个答案就说明了,引用变量指向的都是内存中同一份字节码。

至于用equals方法来比较,其实也是一样的,假设比较的是两个对象,这里面的两个对象字节码相同,自然就返回true。何况指向的都是同一个对象呢?

还有为什么要向下转型的问题,是因为getClass()方法返回的类型是Object类型,在帮助文档里有明确说明。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
package cn.itcast.day1;

public class Practise {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                String s1 = "abc";
                String s2 = new String("abc");
                System.out.println(s1.equals("abc"));  //true
                System.out.println(s1.equals(s2));  //true
               
                System.out.println(s1 == s2);  //false

        }

}

由此可见equal函数比较的是对象在内存中的内容,因为s1与s2内存中的内容都是abc所以返回true。 ==比较的是内存中的内容和地址,因为s1与s2内容相同但是内存地址不同所以返回false

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马