为什么对字符串的引用与其他对象引用的行为不同?

发布于 2024-10-31 22:15:29 字数 506 浏览 1 评论 0原文


在下面的代码中,

public class Test {

    public static void main(String[] args){
        int [] arr = new int[]{1,2};
        String b=new String("abc");
        f(b,arr);
        System.out.println(b);
        System.out.println(arr[0]);

    }

    public static void f(String b, int[] arr){

        b+="de";
        b=null;
        arr[0] = 5;
    }
}

为什么字符串的引用变量的行为与数组的引用变量不同?。
我知道字符串是不可变的,因此对它们的操作会创建新字符串,但是对字符串的引用怎么样,以及引用 b 如何仍然引用旧值,尽管它已更改为引用 f() 方法中的其他内容。

In the following code

public class Test {

    public static void main(String[] args){
        int [] arr = new int[]{1,2};
        String b=new String("abc");
        f(b,arr);
        System.out.println(b);
        System.out.println(arr[0]);

    }

    public static void f(String b, int[] arr){

        b+="de";
        b=null;
        arr[0] = 5;
    }
}

Why the reference variable of the string doesn't behave like the reference variable of the array?.
I know string are immutable so operations on them creates new string but how about references to strings and how the reference b still refer to the old value although it was changed to refer to something else in f() method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

窗影残 2024-11-07 22:15:29

Java 中的对象引用是按值传递的。赋值只是改变值,它不会改变原始对象引用。

在您的示例中,arr[0]已更改,但尝试arr=null,您将看到它在方法返回后没有任何效果。

Object references in Java are passed by value. Assigning just changes the value, it does not alter the original object reference.

In your example arr[0] is changed, but try arr=null and you will see it has no effect after the method has returned.

笔芯 2024-11-07 22:15:29

Java中的方法调用是按值调用的,对此有很长的争论,但我认为我们应该从Java的实现语言(C/C++)来考虑。对象引用只是指向对象的指针,而基元是值。每当调用方法时,实际参数都会复制到形式参数。因此,如果您更改指针以引用另一个对象,则原始指针不受此更改的影响,但如果您更改对象本身,调用方也可以看到更改,因为双方都引用同一个对象。

好吧,在您的示例中,您正在调用的方法中将字符串引用更改为 null,但是您正在更改数组引用引用的对象。这两个操作不同,因此它们确实会产生不同的后果。例如,如果您将代码更改如下,它们在语义上是相同的操作..

arr = null;

Method call is called by value in Java, well there is long debate about this , But I think that we should consider in terms of implementation language of Java which is C/C++. Object references just pointers to objects, and primitives are the values.. Whenever a method is called, actual arguments are copied to formal parameters. Therefore, if you change pointer to reference another object , original pointer is not affected by this change, but if you change object itself, calling party can also see the changes, because both party are referring the same object..

Well, in your example, you are changing string reference to null in called method, but you are changing object referred by array reference.. These two operations are not the same, therefore they do have different consequences.. for example, if you change the code as below, they would be semantically same operation..

arr = null;
始于初秋 2024-11-07 22:15:29

您无法更改任何方法的参数,但可以执行以下操作。

public static void main(String... args) throws IOException {
    String[] strings = {"Hello "};
    addWorld(strings);
    System.out.println("Using an array "+Arrays.toString(strings));

    StringBuilder text = new StringBuilder("Hello ");
    addWorld(text);
    System.out.println("Using a StringBuilder '" + text+"'");
}

private static void addWorld(String[] strings) {
    for(int i=0;i<strings.length;i++)
        strings[i] += "World!";
    strings = null; // doesn't do anything.
}

private static void addWorld(StringBuilder text) {
    text.append("World !!");
    text = null; // doesn't do anything.
}

印刷

Using an array [Hello World!]
Using a StringBuilder 'Hello World !!'

You cnanot change the argument for any method, however you can do the following.

public static void main(String... args) throws IOException {
    String[] strings = {"Hello "};
    addWorld(strings);
    System.out.println("Using an array "+Arrays.toString(strings));

    StringBuilder text = new StringBuilder("Hello ");
    addWorld(text);
    System.out.println("Using a StringBuilder '" + text+"'");
}

private static void addWorld(String[] strings) {
    for(int i=0;i<strings.length;i++)
        strings[i] += "World!";
    strings = null; // doesn't do anything.
}

private static void addWorld(StringBuilder text) {
    text.append("World !!");
    text = null; // doesn't do anything.
}

prints

Using an array [Hello World!]
Using a StringBuilder 'Hello World !!'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文