Java is NEVER pass-by-reference, right?…right? [duplicate]

不想你离开。 提交于 2019-12-17 09:09:37

问题


Possible Duplicate:
Is Java “pass-by-reference”?

I found an unusual Java method today:

private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
     if (null == vsName)
       vsName = "";
     else
       vsName = vsName.trim();
     String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
     //SCR10638 - Prevent export of empty rows.
     if (shortenedVoiceSetName.length() > 0)
     {
       if (!voiceSetList.contains("#" + shortenedVoiceSetName))
         voiceSetList.add("#" + shortenedVoiceSetName);
     }
}

According to everything I've read about Java's behavior for passing variables, complex objects or not, this code should do exactly nothing. So um...am I missing something here? Is there some subtlety that was lost on me, or does this code belong on thedailywtf?


回答1:


As Rytmis said, Java passes references by value. What this means is that you can legitimately call mutating methods on the parameters of a method, but you cannot reassign them and expect the value to propagate.

Example:

private void goodChangeDog(Dog dog) {
    dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
    dog = new StBernard(); // compiles, but has no effect outside the method
}

Edit: What this means in this case is that although voiceSetList might change as a result of this method (it could have a new element added to it), the changes to vsName will not be visible outside of the method. To prevent confusion, I often mark my method parameters final, which keeps them from being reassigned (accidentally or not) inside the method. This would keep the second example from compiling at all.




回答2:


Java passes references by value, so you get a copy of the reference, but the referenced object is the same. Hence this method does modify the input list.




回答3:


The references themselves are passed by value.

From Java How to Program, 4th Edition by Deitel & Deitel: (pg. 329)

Unlike other languages, Java does not allow the programmer to choose whether to pass each argument by value or by reference. Primitive data type variables are always passed by value. Objects are not passed to methods; rather, references to objects are passed to methods. The references themselves are passed by value—a copy of a reference is passed to a method. When a method receives a reference to an object, the method can manipulate the object directly.

Used this book when learning Java in college. Brilliant reference.

Here's a good article explaining it. http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html




回答4:


Well, it can manipulate the ArrayList - which is an object... if you are passing an object reference around (even passed by value), changes to that object will be reflected to the caller. Is that the question?




回答5:


I think you are confused because vsName is modified. But in this context, it is just a local variable, at the exact same level as shortenedVoiceSetName.




回答6:


It's not clear to me what the exact question within the code is. Java is pass-by-value, but arrays are pass-by-reference as they pass no object but only pointers! Arrays consist of pointers, not real objects. This makes them very fast, but also makes them dangerous to handle. To solve this, you need to clone them to get a copy, and even then it will only clone the first dimension of the array.

For more details see my answer here: In Java, what is a shallow copy? (also see my other answers)

By the way, there are some advantages as arrays are only pointers: you can (ab)use them as synchronized objects!



来源:https://stackoverflow.com/questions/795160/java-is-never-pass-by-reference-right-right

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!