黑马程序员技术交流社区

标题: 反射的一个小疑问 [打印本页]

作者: 陈嘉宾    时间: 2012-6-21 20:01
标题: 反射的一个小疑问
本帖最后由 陈嘉宾 于 2012-6-22 14:47 编辑

        这个pt1不是用来传入修改x,y的值吗?为什么下面替换a,b的时候changeStringValue(pt1);为什么还要把pt1传进去?
public static void main(String[] args) throws Exception{
ReflectPoint pt1=new ReflectPoint(3,5);
                Field fieldY=pt1.getClass().getField("y");
                System.out.println(fieldY.get(pt1));
                Field fieldX=pt1.getClass().getDeclaredField("x");
                fieldX.setAccessible(true);
                System.out.println(fieldX.get(pt1));  
               
                changeStringValue(pt1);
                System.out.println();
        }

        private static void changeStringValue(Object obj) throws Exception{
                Field[] fileds=obj.getClass().getFields();
                for(Field field:fileds){
                        //if(field.getType().equals(String.class)){;
                        if(field.getType()==String.class){
                                String oldValue =(String)field.get(obj);
                                String newValue=oldValue.replace('b','a');
                                field.set(obj, newValue);
                        }

public class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";

public ReflectPoint(int x, int y) {
                 super();
                 this.x = x;
                 this.y = y;
         }
         @Override
         public String toString(){
                 return str1+":"+str2+":"+str3;
         }
}


作者: 李元峰    时间: 2012-6-21 20:10
ReflectPoint rp = new ReflectPoint(5, 6);这里为什么要传5,6进去呢?不明白是啥意思啊。。
//这里是调用了 ReflectPoint这个类的构造器,一定有这样一个构造器,public ReflectPoint(int x, int y)来创建一个ReflectPoint对象并初始化成员变量

public class ReflectTest2 {
public static void main(String[] args) throws Exception {
changeString();
}

private static void changeString() throws Exception {
// TODO Auto-generated method stub
ReflectPoint rp = new ReflectPoint(5, 6);
Field[] fields = rp.getClass().getFields();

for (Field field : fields) {
if (field.getType() == String.class) {
//比较两份字节码是否相同,所以要用 == 而不用 equals
//问题在这里:   field.getType和 field.getClass返回的都是Class,它们有什么区别呢?  
//  field.getType     返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
String strOld = (String) field.get(rp);   Field没有getClass() 方法


怎么我把代码粘贴上来,前面的空格就没了呢,这样看太乱了。//因为你复制过来的编排的格式在这里不起作用了
String strNew = strOld.replace("b", "hi,");
field.set(rp, strNew);
}
}
System.out.println(rp);
}
}

class ReflectString {
public String str1 = "bhaoma";
public String str2 = "bnihao";
public String str3 = "bwobuhao";


public String toString() {
return str1 +":" + str2 + ":" + str3;
}
}

作者: 李元峰    时间: 2012-6-21 20:16
这个pt1不是用来传入修改x,y的值吗?为什么下面替换a,b的时候changeStringValue(pt1);为什么还要把pt1传进去?
//老师是这样讲的,因为pt1.getClass().getDeclaredField("x")得到的 Field 对象是.class 字节码上的域对象的Field对象,他不属于任何的对象,他只是通知某个具体的对象要修改自己的值
所以下面private static void changeStringValue(Object obj) 方法 传递了需要修改的 obj 对象的 String 类型的值,他的作用是通知某个具体的对象,告诉他,你去改变我代表的那个字段的值
只是向要改变的对象发送消息,
public static void main(String[] args) throws Exception{
ReflectPoint pt1=new ReflectPoint(3,5);
                Field fieldY=pt1.getClass().getField("y");
                System.out.println(fieldY.get(pt1));
                Field fieldX=pt1.getClass().getDeclaredField("x");
                fieldX.setAccessible(true);
                System.out.println(fieldX.get(pt1));  
               
                changeStringValue(pt1);
                System.out.println();
        }

        private static void changeStringValue(Object obj) throws Exception{
                Field[] fileds=obj.getClass().getFields();
                for(Field field:fileds){
                        //if(field.getType().equals(String.class)){;
                        if(field.getType()==String.class){
                                String oldValue =(String)field.get(obj);
                                String newValue=oldValue.replace('b','a');
                                field.set(obj, newValue);
                        }

public class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";

public ReflectPoint(int x, int y) {
                 super();
                 this.x = x;
                 this.y = y;
         }
         @Override
         public String toString(){
                 return str1+":"+str2+":"+str3;
         }
}


作者: 李元峰    时间: 2012-6-21 20:18
我建议当你不明白某个方法时,你应该首先去参考API,我通常这么做,仔仔细细的看,返回类型,参数,以及用法,异常
作者: 陈嘉宾    时间: 2012-6-21 20:22
我还是去再看一下吧~虽然我还是没明白,我再理解理解。。。谢谢
作者: 陈嘉宾    时间: 2012-6-21 20:48
李元峰 发表于 2012-6-21 20:18
我建议当你不明白某个方法时,你应该首先去参考API,我通常这么做,仔仔细细的看,返回类型,参数,以及用 ...

主要就是ReflectPoint pt1=new ReflectPoint(3,5);传入3,5对public class ReflectPoint中修改String类的值有什么关系假如public class ReflectPoint中只有public String str1="ball";
public String str2="basketball";
public String str3="itcast";呢?
作者: 李元峰    时间: 2012-6-21 21:16
本帖最后由 李元峰 于 2012-6-21 21:17 编辑
陈嘉宾 发表于 2012-6-21 20:48
主要就是ReflectPoint pt1=new ReflectPoint(3,5);传入3,5对public class ReflectPoint中修改String类的 ...

因为 ReflectPoint 定义了 两个变量 x,y,所以就提供了带参数的构造器对每个新创建的对象的成员进行初始化,
传入 3,5 对public class ReflectPoint中修改String类的值 没有任何关系,你甚至还以修改 传递进去的3,和5的值,你还可以这样 if(field.getType()==int.class){//表示得到的字段类型为int
    //这里面就是对int 类型的 x,y,进行修改了
  //像这样:
          if(field.getName().equals("x")){
                    field.set(pt1,9);//把 3改成了9   
    }
      if(field.getName().eaual("y")){
                      field.set(pt1,0);//把 5改成了0   
              }
}
作者: 陈嘉宾    时间: 2012-6-21 21:29
本帖最后由 陈嘉宾 于 2012-6-21 21:39 编辑

验证了一下如果有x,y的构造方法,就要新建一个带ReflectPoint pt2=new ReflectPoint(3,5);函数的构造方法,如果public ReflectPoint(int x, int y) {                    super();
                 this.x = x;
                 this.y = y;没有     就用无参的?ReflectPoint pt2=new ReflectPoint();我这么理解对吗




public class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";

public ReflectPoint(int x, int y) {
                 super();
                 this.x = x;
                 this.y = y;
        }
        @Override
        public String toString(){
                return str1+":"+str2+":"+str3;
        }
}

作者: 陈嘉宾    时间: 2012-6-21 21:39
李元峰 发表于 2012-6-21 21:16
因为 ReflectPoint 定义了 两个变量 x,y,所以就提供了带参数的构造器对每个新创建的对象的成员进行初始化 ...


本帖最后由 陈嘉宾 于 2012-6-21 21:39 编辑


验证了一下如果有x,y的构造方法,就要新建一个带ReflectPoint pt2=new ReflectPoint(3,5);函数的构造方法,如果public ReflectPoint(int x, int y) {                    super();
                 this.x = x;
                 this.y = y;没有     就用无参的?ReflectPoint pt2=new ReflectPoint();我这么理解对吗




public class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="itcast";

public ReflectPoint(int x, int y) {
                 super();
                 this.x = x;
                 this.y = y;
        }
        @Override
        public String toString(){
                return str1+":"+str2+":"+str3;
        }
}
作者: 李元峰    时间: 2012-6-21 21:44
陈嘉宾 发表于 2012-6-21 21:39
本帖最后由 陈嘉宾 于 2012-6-21 21:39 编辑

是的,你可以现在就写代码测试一下,验证你的猜想,然后在打印他们的值,你会发现他们的值 都是 0,0(如果你没有显示的初始化)
作者: 陈嘉宾    时间: 2012-6-21 22:13
李元峰 发表于 2012-6-21 21:44
是的,你可以现在就写代码测试一下,验证你的猜想,然后在打印他们的值,你会发现他们的值 都是 0,0(如 ...

恩我明白了谢谢你~哈哈
作者: 陈嘉宾    时间: 2012-6-21 22:13
李元峰 发表于 2012-6-21 21:44
是的,你可以现在就写代码测试一下,验证你的猜想,然后在打印他们的值,你会发现他们的值 都是 0,0(如 ...

恩我明白了谢谢你~哈哈




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2