Java中的字符串是对象,所以它应该是引用?

时间:2014-03-15 08:43:11

标签: java

我是Java的初学者,最近遇到了关于Java String概念的面试问题:

public class Test1 {

    public static void changeStr(String str){
        str="welcome";
    }

    public static void main(String[] args) {
        String str="1234";
        changeStr(str);
        System.out.println(str);
     }
}

我认为输出应该是“welcome”,但是,我在Eclipse中测试它,它显示“1234”,不是Java字符串是引用,所以Java字符串“str”引用变为“welcome”在方法changeStr?

请原谅我的初学者问题!

5 个答案:

答案 0 :(得分:4)

将对象的引用传递给方法并分配给参数,该参数是一种局部变量。

为参数分配不同的对象引用不会对保存对原始对象的引用的方法外的变量执行任何操作。

String也是不可变的,因此无法更改其值(例如setValue()方法)。

答案 1 :(得分:2)

str = "welcome";不会更改任何String的值 - 字符串永远不会更改其值。它的作用是使一个参考点指向不同的String。但是它重新指定的引用是changeStr的本地引用,而不是main中声明的引用。

答案 2 :(得分:1)

字符串是一个引用,但关键是String str中的changeStr与main中的str不同。再加上字符串在Java中是不可变的这一事实(意味着当您更改String时,引用指向内存中的其他位置)并解释了为什么main将打印1234

答案 3 :(得分:1)

考虑以下示例:

public static void main(final String[] args) throws Exception {
    final StringHolder holder = new StringHolder("old value");
    System.out.println(holder);
    reassignHolder(holder);
    System.out.println(holder);
    changeVal(holder);
    System.out.println(holder);
}

static void reassignHolder(StringHolder holder) {
    holder = new StringHolder("new value");
}

static void changeVal(StringHolder holder) {
    holder.setVal("new value");
}

static class StringHolder {

    private String val;

    public StringHolder(String val) {
        this.val = val;
    }

    public String getVal() {
        return val;
    }

    public void setVal(String val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "StringHolder{" + "val=" + val + '}';
    }

}

在Java中,引用按值传递,(几乎)所有内容都是对象引用。

这里我们有一个可变对象,其中包含String - StringHolder

当我们调用reassignHolder我们实际做的是复制我们的对象引用并将其传递给方法。当方法重新分配时,我们传递副本时,我们的原始引用没有任何反应。

当我们调用reassignHolder时,我们也传递了引用的副本,但该方法使用此引用来调用对象上的方法来更改其val变量。这会产生影响。

所以输出是:

StringHolder{val=old value}
StringHolder{val=old value}
StringHolder{val=new value}

由于String是不可变的,你只能执行第一个例子而不是第二个例子。

答案 4 :(得分:0)

这里的逻辑是传递的str值作为str的引用副本传递。这意味着str中的任何更改都不会反映在原始str中。 这种情况类似于按值传递(但是参考!)

但是在您的代码中,如果您将代码更改为str = new String("welcome");它会更改原始str字符串,方法是引用已创建的新副本。

希望这能为你解决问题。