非常奇怪的问题。相同的变量,最后输出结果不一样。

lgmsyy 2014-06-11 07:32:56
Template template = (Template)entry.getValue();

//分别赋值给 tzsj1 tzsj2 变量
byte[] tzsj1 = template.getTzsj();
byte[] tzsj2 = template.getTzsj();

if("1".equals(sfzh)){//生成11 22 txt文件
this.bytesToFile("/gfserver/lib/11.txt", tzsj1);//通过tzsj1
this.bytesToFile("/gfserver/lib/22.txt", tzsj2);//通过tzsj2
}

scoreFloat = com.byteFeature(imgBytes, tzsj1);//注意我传的是tzsj1

if("1".equals(sfzh)){//33 44 txt文件
this.bytesToFile("/gfserver/lib/33.txt", tzsj1);//通过tzsj1
this.bytesToFile("/gfserver/lib/44.txt", tzsj2);//通过tzsj2
}


问题来了,奇怪的问题,非常奇怪
当我执行 scoreFloat = com.byteFeature(imgBytes, tzsj1); 后,
发现 11.txt,22.txt相同;33.txt,44.tx相同。但是但是,11.txt和33.txt不相同,22.txt和44.txt不相同

但是,当我不执行 com.byteFeature(imgBytes, tzsj1)后,发现11.txt ,22.txt,33.txt,44.txt相同。

以下仅仅是输出文件代码
private void bytesToFile(String path, byte[] content) throws IOException {
FileOutputStream out = new FileOutputStream(path);
out.write(content);
out.close();
}
...全文
300 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lgmsyy 2014-06-12
  • 打赏
  • 举报
回复
..... Template template = (Template)entry.getValue(); byte[] tzsj1 = template.getTzsj(); byte[] tzsj2 = template.getTzsj(); scoreFloat = com.byteFeature(imgBytes, tzsj1);//这个实际是调用Linux下 C++ 生成的SO的函数 使我感到奇怪的是,为什么在执行byteFeature函数后(注意我传入的仅仅是tzsj1),tzsj1中的值改变了,并且tzsj2的值也被改变了呢? 难道是刚开始tzsj1和tzsj2都同时指向一个内存地址,在执行byteFeature函数后,C语言经过某种处理,修改了tzsj1的是,又回传给JAVA, 结果导致 tzsj1 和 tzsj2都随着 tzsj1 的改变而改变了? 如果是这样的话,我该如何保留一份原始的 template.getTzsj()值呢?
引用 3 楼 magi1201 的回复:
他们取自同一个 template.getTzsj(),第一次取时,内存给 template.getTzsj() 分配一块空间,存放 template.getTzsj() 数组,tzsj1 指向它。第二次tzsj2 直接指向了 template.getTzsj() ,所以tzsj1 和 tzsj2 始终指向同一块内存地址。 如下示例,class省略get set方法。

public class Ca {
    private String id;
    private String name;
    
    public Ca (String id, String name) {
        this.id = id;
        this.name = name;
    }

public class Cb {
    private String id;
    private Ca ca;
    
    public Cb(String id, Ca ca) {
        this.id = id;
        this.ca = ca;
    }    
}


        Ca ca = new Ca("id1", "name1");
        Cb cb = new Cb("id2", ca);
        
        Ca c1 = cb.getCa();
        Ca c2 = cb.getCa();
        
        c1.setId("idd");
        
        System.out.println(cb.getCa().getId());
        System.out.println(c2.getId());
c1.setId("idd"); 的修改,会影响到cb 和 c2
姜小白- 2014-06-12
  • 打赏
  • 举报
回复
他们取自同一个 template.getTzsj(),第一次取时,内存给 template.getTzsj() 分配一块空间,存放 template.getTzsj() 数组,tzsj1 指向它。第二次tzsj2 直接指向了 template.getTzsj() ,所以tzsj1 和 tzsj2 始终指向同一块内存地址。 如下示例,class省略get set方法。

public class Ca {
    private String id;
    private String name;
    
    public Ca (String id, String name) {
        this.id = id;
        this.name = name;
    }

public class Cb {
    private String id;
    private Ca ca;
    
    public Cb(String id, Ca ca) {
        this.id = id;
        this.ca = ca;
    }    
}


        Ca ca = new Ca("id1", "name1");
        Cb cb = new Cb("id2", ca);
        
        Ca c1 = cb.getCa();
        Ca c2 = cb.getCa();
        
        c1.setId("idd");
        
        System.out.println(cb.getCa().getId());
        System.out.println(c2.getId());
c1.setId("idd"); 的修改,会影响到cb 和 c2
lgmsyy 2014-06-12
  • 打赏
  • 举报
回复
引用 1 楼 magi1201 的回复:

       //分别赋值给 tzsj1 tzsj2 变量
        // tzsj1 和 tzsj2 指向相同的内存空间
        byte[] tzsj1 = template.getTzsj();
        byte[] tzsj2 = template.getTzsj();

        if("1".equals(sfzh)){//生成11 22 txt文件
           // bytesToFile 不对第二个参数做修改,故tzsj1和tzsj2 依然是之前的样子,且相同
            // 同时 11.txt 和 22.txt 也相同
           this.bytesToFile("/gfserver/lib/11.txt", tzsj1);//通过tzsj1
           this.bytesToFile("/gfserver/lib/22.txt", tzsj2);//通过tzsj2
        } 
        
        // byteFeature 这个方法,应该会对传参做修改
        // 故不经过此方法,四个文件相同,经过此方法,文件两两相同,但不四个相同
        scoreFloat = com.byteFeature(imgBytes, tzsj1);//注意我传的是tzsj1
        
        if("1".equals(sfzh)){//33 44 txt文件
            // tzsj1 和 tzsj2 相同,故33.txt 和 44.txt 相同
            this.bytesToFile("/gfserver/lib/33.txt", tzsj1);//通过tzsj1
            this.bytesToFile("/gfserver/lib/44.txt", tzsj2);//通过tzsj2
        }
tzsj1 和 tzsj2 始终相同,两次结果不同的影响因素就是byteFeature 方法了
关键的问题就是 // tzsj1 和 tzsj2 指向相同的内存空间 ,为什么指向了同一个内存空间,又不是String 这种类型的?
姜小白- 2014-06-12
  • 打赏
  • 举报
回复
之前的Ca 添加Cloneable实现

public class Ca implements Cloneable{
    
    private String id;
    private String name;
    
    public Ca (String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public  Object clone() throws CloneNotSupportedException  {
        Ca cloneObj = (Ca) super.clone();
        return cloneObj;
    }
    
然后

    public static void main(String[] args) throws CloneNotSupportedException {
        Ca ca = new Ca("id1", "name1");
        Cb cb = new Cb("id2", ca);
        
        Ca c = (Ca) cb.getCa().clone();
        
        Ca c1 = cb.getCa();
        c1.setId("idd");
        
        System.out.println(cb.getCa().getId());
        System.out.println(c.getId());
    }
此时,c 为拷贝出去的Ca对象,c1 的修改不影响c 了。跟着楼主的问题,了解了下clone
tony4geek 2014-06-12
  • 打赏
  • 举报
回复
看看 java 深拷贝和浅拷贝
tony4geek 2014-06-12
  • 打赏
  • 举报
回复
来看看学习。
姜小白- 2014-06-12
  • 打赏
  • 举报
回复
引用 4 楼 lgmsyy 的回复:
..... Template template = (Template)entry.getValue(); byte[] tzsj1 = template.getTzsj(); byte[] tzsj2 = template.getTzsj(); scoreFloat = com.byteFeature(imgBytes, tzsj1);//这个实际是调用Linux下 C++ 生成的SO的函数 使我感到奇怪的是,为什么在执行byteFeature函数后(注意我传入的仅仅是tzsj1),tzsj1中的值改变了,并且tzsj2的值也被改变了呢? 难道是刚开始tzsj1和tzsj2都同时指向一个内存地址,在执行byteFeature函数后,C语言经过某种处理,修改了tzsj1的是,又回传给JAVA, 结果导致 tzsj1 和 tzsj2都随着 tzsj1 的改变而改变了? 如果是这样的话,我该如何保留一份原始的 template.getTzsj()值呢?
clone Cloneable java中clone理解
姜小白- 2014-06-11
  • 打赏
  • 举报
回复

       //分别赋值给 tzsj1 tzsj2 变量
        // tzsj1 和 tzsj2 指向相同的内存空间
        byte[] tzsj1 = template.getTzsj();
        byte[] tzsj2 = template.getTzsj();

        if("1".equals(sfzh)){//生成11 22 txt文件
           // bytesToFile 不对第二个参数做修改,故tzsj1和tzsj2 依然是之前的样子,且相同
            // 同时 11.txt 和 22.txt 也相同
           this.bytesToFile("/gfserver/lib/11.txt", tzsj1);//通过tzsj1
           this.bytesToFile("/gfserver/lib/22.txt", tzsj2);//通过tzsj2
        } 
        
        // byteFeature 这个方法,应该会对传参做修改
        // 故不经过此方法,四个文件相同,经过此方法,文件两两相同,但不四个相同
        scoreFloat = com.byteFeature(imgBytes, tzsj1);//注意我传的是tzsj1
        
        if("1".equals(sfzh)){//33 44 txt文件
            // tzsj1 和 tzsj2 相同,故33.txt 和 44.txt 相同
            this.bytesToFile("/gfserver/lib/33.txt", tzsj1);//通过tzsj1
            this.bytesToFile("/gfserver/lib/44.txt", tzsj2);//通过tzsj2
        }
tzsj1 和 tzsj2 始终相同,两次结果不同的影响因素就是byteFeature 方法了

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧