在Java中,数组类型的字段是深复制还是浅复制? - java

[背景说明:我是一位具有C ++背景的新Java程序员,因此对于如何在Java中传递参数有些困惑。]

在阅读和编写一些代码时,我遇到以下情况

public class B{
    int[] intArr;
    Vector<String> strVec;

    void mutator(){
        // modifies intArr and strVec
    }
}

public class A{
    B bOfA;

    A(B b){
        bOfA = b;
    }

    void foo(){
        bofA.mutator();
    }
}

A中的foo()肯定会修改bOfA,但是传入的对象b呢?是否会修改其字段/数据成员?

字段是浅复制还是深复制?

strVec和intArr的处理方式有所不同,因为strVec是一个容器,而inArr是一个数组,可以将其实现为某种指针,因此根据其是浅复制还是深复制,其行为会有很大不同。

谢谢。

使用实际代码进行的(最新)更新,并且有些令人惊讶(我假设是以C / C ++方式解释的传递值机制):

import java.util.Vector;

public class B{
    int[] intArr = null;
    Vector<String> strVec = null;
    int x = 0;
    String s = null;

    B(int sz){

        x = 0;
        s = new String("ini");

        intArr = new int[sz];
        strVec = new Vector<String>(sz);

        for (int i=0; i<sz; i++){
            intArr[i] = 0;
            strVec.add( new String("xx") );
        }
    }

    void mutator(){

        x = -1;
        s = new String("mute");

        int sz = intArr.length;
        strVec = new Vector<String>(sz);

        for (int i=0; i<sz; i++){
            intArr[i] = -1;
            strVec.add( new String("aa") );
        }
    }
}


import java.util.Vector;

public class A{

    B bOfA=null;

    A(B b){
        bOfA = b;
    }

    void foo(){
        bOfA.mutator();
    }
}



import java.util.Vector;

public class C{

    public static void main(String[] args){
        B b = new B(3);

        A a = new A(b);

        System.out.println("Contents of B before:");
        System.out.println(b.x);
        System.out.println(b.s);
        for(int i=0; i<3; i++){
            System.out.println(b.intArr[i]);
            System.out.println(b.strVec.elementAt(i));
        }

        a.foo();

        System.out.println("\n\nContents of A:");
        System.out.println(a.bOfA.x);
        System.out.println(a.bOfA.s);
        for(int i=0; i<3; i++){
            System.out.println(a.bOfA.intArr[i]);
            System.out.println(a.bOfA.strVec.elementAt(i));
        }
        System.out.println("\n\nContents of B after:");
        System.out.println(b.x);
            System.out.println(b.s);
        for(int i=0; i<3; i++){
            System.out.println(b.intArr[i]);
            System.out.println(b.strVec.elementAt(i));
        }
    }

}

cygwin的结果:

Contents of B before:
0
ini
0
xx
0
xx
0
xx


Contents of A:
-1
mute
-1
aa
-1
aa
-1
aa


Contents of B after:
-1
mute
-1
aa
-1
aa
-1
aa

java大神给出的解决方案

数组是参考对象。分配它们时,它们根本不会被复制-发生的事情类似于在C ++中将数组分配给指针。

使用System.arraycopy复制数组时,将执行浅表复制。从另一个集合构造一个集合也会创建一个浅表副本。

注意:与C ++库不同,Java类库大量使用不可变类。例如,String是不可变的。数字包装程序也是如此,例如Integer。不变性使浅复制和深复制的相关性大大降低。

另一个注意事项:当需要同步容器时,应使用Vector<T>。如果不想同步,请使用ArrayList<T>

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

如何修改休眠的SQL查询? - java

我有点好奇,有没有办法修改hibernate的核心,以便我可以自定义生成的SQL query。例如,在生成的查询中添加功能以使用connect by prior(oracle)或我要自定义的任何其他子句。 java大神给出的解决方案 起初,这样的问题总是在我心中敲响警钟。你被警告了...AFAIK,hibernate使用所谓的dialects进行特定的优化。…

用Java构建大批量数据处理工具 - java

Closed. This question needs to be more focused。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。 3年前关闭。 Improve this question 我正在尝试使用Java构建ETL工具。 ETL工具用于对大量数据(关系型和其他类型)进行批量读取,…

用Java封装对象? - java

private中的Java提供类级别的封装。可以封装一个对象吗?还是这样做徒劳?例如,如果我们将一个类定义为 public class Person { private String ssn; private ArrayList<Person> friends = new ArrayList<Person>(); public voi…

使用TDD和Java开发的开源项目 - java

Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以使为on-topic。 5年前关闭。 Improve this question 我正在寻找一个项目:1)包括测试在内的可用资源。2)已/已严格使用TDD开发。3)用Java和JUnit…