2014-06-30 25 views
-1

我是新手。
我读过,局部变量的范围将在一个块内(纠正我,如果我错了)。 在这里,主要方法的局部变量(名单lili1和StringBuffer的y)表现得像个实例变量,而这些变量(字符串y1和int x)行为类似于局部变量。为什么?带有列表,字符串和字符串缓冲区的局部变量行为

public class Test { 
    public static void addValues(ArrayList<String> list, StringBuffer sb, int x){ 
     list.add("3"); 
     list.add("4"); 
     list.add("5"); 

     sb.append("String Buffer Appended !"); 
     x=x+10; 
    } 

    public static void addValues(ArrayList<String> list, String sb, int x){ 
     list.add("3"); 
     list.add("4"); 
     list.add("5"); 

     sb = sb + "is Appended !"; 
     x=x+10; 
    } 

    public static void main(String[] args) { 
     ArrayList<String> li = new ArrayList<>(); 
     ArrayList<String> li1 = new ArrayList<>(); 
     StringBuffer y=new StringBuffer("ab"); 
     int x=10; 
     String y1=new String("ab"); 
     li.add("1"); 
     li.add("2"); 
     li1.add("1"); 
     li1.add("2"); 
     System.out.println("b4 : "+li+" , y = "+y+" , y1 = "+y1+" x= "+x); 
     addValues(li,y,x); 
     System.out.println("Af : "+li+" , y = "+y+" x= "+x); 
     addValues(li1,y1,x); 
     System.out.println("Af : "+li1+" , y1 = "+y1+" x= "+x); 
    } 
} 

输出:

b4 : [1, 2] , y = ab , y1 = ab x= 10 
Af : [1, 2, 3, 4, 5] , y = abString Buffer Appended ! x= 10 
Af : [1, 2, 3, 4, 5] , y1 = ab x= 10 
+1

另请参阅http://stackoverflow.com/questions/4658453/difference-between-mutable-objects-and-immutable-objects –

+0

对不起,发布此作为答案,因为我的声誉确实不允许我评论你的问题。但这个问题被多次询问。在这里,检查[this](https://stackoverflow.com/questions/15871825/why-is-an-arraylist-parameter-modified-but-not-a-string-parameter),[this](https:// stackoverflow.com/questions/8798403/string-is-immutable-what-exactly-is-the-meaning)和[this](https://stackoverflow.com/questions/40480/is-java-pass-by-reference -or通按值) – epipav

回答

3

在该ArrayList和StringBuffer的情况下,要传递到一个可变对象反映上保持相同的参考任何变量任何修改的参考。

在字符串的情况下,你太传递一个参考,但其不变的,所以当您连接东西给它,它实际上是创建一个新的String对象和方法内分配一个新的参考变量,你实际上并没有修改对象本身。

而在INT的情况下,所有的基元分配和按值传递的,所以它实际上使得它的价值的副本,并将其传递给方法,所以任何你做给该变量的方法中犯规影响变量以外。

0

Java总是按值传递,意味着它总是将变量(原始变量和引用变量)的副本传递给方法的代码块。

当我们传递一个对象引用变量(在这种情况下,ArrayList和StringBuffer的),其实我们要复制有位模式引用变量,而不是真正的对象是自己,在你的addValues法新副本是指完全相符与在main方法中声明的对象相同,因此无论何时修改对象成员的值,copy和actuall对象引用变量都会看到更改。

默认情况下,字符串是不可变的,而且默认情况下它们是不可变的。所以无论何时我们将它们作为参数传递给方法,这些方法只会从String和int中获取值的副本。

您在java中与“Stack and Heap”有关的问题。你可以看this video作为参考