TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Java is Pass-by-Value, Dammit

218 点作者 xvirk大约 10 年前

27 条评论

nickbauman大约 10 年前
Well the way I've always thought of it is that Java passes "references by value". Meaning the target method receives a _copy_ of the pointer, not the actual pointer. So the result of newing up the parameter inside the target method doesn't affect the original, because you're just making the pointer point to a NEW memory address. On the other hand, mutating the parameter WILL affect the original object, because a copy of a pointer still points to that object from the caller.
评论 #9245481 未加载
评论 #9245530 未加载
评论 #9245415 未加载
AnthonyMouse大约 10 年前
So to summarize, you have a Java function:<p><pre><code> public void f(Foo bar) { ... } </code></pre> Which is the equivalent C++ function?<p><pre><code> void f(Foo bar) { ... } void f(Foo&amp; bar) { ... } void f(Foo* bar) { ... } </code></pre> It&#x27;s the last one. Java passes everything by value, but non-primitive objects in Java are actually pointers (which Java inaccurately calls references), and the <i>pointer</i> is passed by value.
评论 #9247077 未加载
评论 #9246865 未加载
评论 #9247013 未加载
评论 #9246769 未加载
zvrba大约 10 年前
Of course it is. It says so in the language spec, and even in the official tutorial here: <a href="http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" rel="nofollow">http:&#x2F;&#x2F;docs.oracle.com&#x2F;javase&#x2F;tutorial&#x2F;java&#x2F;javaOO&#x2F;arguments...</a><p>Swap is a nice litmus test.<p>To people who claim that Java doesn&#x27;t have pointers, I counter-argument by the fact that you can make a circular doubly-linked list in Java. Thus, a reference is a pointer though with lesser capabilities than in C++. In contrast, you cannot make a circular doubly-linked list with C++ references which are object aliases.<p>Actually, I have the following analogy: pointer ~ symbolic link; reference ~ hard link.<p>Java&#x27;s references are misnamed.
评论 #9245883 未加载
评论 #9246023 未加载
评论 #9246549 未加载
lucio大约 10 年前
This topic (I do not know why) raises some serious emotion-based responses on coders. The other topic I know will cause almost a religious flame-war is the philosophical meaning of &quot;null&quot; in the SQL arena.<p>I&#x27;ve tried to add some insight why the OP hears (so many) &gt;folks (incorrectly) state &quot;primitives are passed by value, objects are passed by reference&quot;<p>What I believe was my constructive addition to the topic, seems to deserve only downvotes. I&#x27;ll make a reminder to not participate again in this kind of topics.
评论 #9245856 未加载
评论 #9245628 未加载
furyofantares大约 10 年前
The confused terminology isn&#x27;t related to function calls. In Java, objects are not values.<p>The confused terminology originates before you get to function calls -- you can&#x27;t ask &quot;are objects passed by value?&quot; without first considering objects as values. Objects can&#x27;t be stored in variables and objects cannot be the result of an expression. x = y does not copy an object y into an object x because objects are not values -- x and y are variables and they can only hold values, which objects are not.
Osiris大约 10 年前
I work full-time in JavaScript and I&#x27;ve always thought of JavaScript as a pass-by-reference but this article made it clear that JavaScript is pass-reference-by-value. The `swap` function from the article doesn&#x27;t swap the variables outside of the function.
评论 #9245835 未加载
DonHopkins大约 10 年前
<p><pre><code> From: James Gosling Date: 1&#x2F;13&#x2F;11 Don Hopkins wrote: &gt;Hey I know it&#x27;s 2011 and we&#x27;re living in the future and all that, but &gt;there still seems to be some confusion and debate about a matter I &gt;thought was perfectly clear: Is Java pass by value or pass by &gt;reference? Depends on your terminology. But it&#x27;s kinda both. It&#x27;s pass-by-value for everything, with the twist that for class instances, the thing that&#x27;s passed-by-value is the pointer to the object, so it behaves like pass-by-reference. From: Don Hopkins Date: 1&#x2F;13&#x2F;11 Reminds me of the controversy about Niklaus Wirth&#x27;s name: &quot;Whereas Europeans generally pronounce his name the right way (&#x27;Nick-louse Veert&#x27;), Americans invariably mangle it into &#x27;Nickel&#x27;s Worth.&#x27; This is to say that Europeans call him by name, but Americans call him by value.&quot; - Introduction by Adriaan van Wijngaarden at the IFIP Congress (1965). It seems to be a consequence of pretending pointers don&#x27;t exist -- you also have to pretend you have variables with object values and references, but you still can&#x27;t write a swap(a, b) function. If you think of Java object values as pointers, then it&#x27;s obviously passing references by value. But if you don&#x27;t believe in pointers and think of variables as containing objects, then it&#x27;s obviously passing objects by reference, but your view of the world is an illusion, because it&#x27;s really implemented with pointers. Or is it??? Someone suggested a Magic Elves theory, which helps a lot of other stuff to make more sense. </code></pre> Here&#x27;s the discussion from 2011 about this issue that prompted me to ask James Gosling for a clarification. You can see that many people were VERY confused, and extremely fanatical about maintaining and spreading their confusion, in spite of the fact that it directly contradicted the Java spec and the inventor of Java himself.<p>Java is PASS BY VALUE.<p><a href="http://www.theserverside.com/discussions/thread.tss?thread_id=61622" rel="nofollow">http:&#x2F;&#x2F;www.theserverside.com&#x2F;discussions&#x2F;thread.tss?thread_i...</a>
评论 #9246751 未加载
viraptor大约 10 年前
I gave up on this... It&#x27;s explicitly said in the Java standard that the language is pass-by-value. On one occasion I&#x27;ve been told that the standard must be wrong then. Some people just don&#x27;t want to accept reality if it doesn&#x27;t match their interpretation of definitions. :-(
评论 #9245942 未加载
评论 #9246123 未加载
carsongross大约 10 年前
Java hides the pointer, which is what confuses people.<p>Maybe we shouldn&#x27;t be shitty about that, since it doesn&#x27;t really matter too much.<p>Just a thought.
mml大约 10 年前
This entire thread makes me want to die. Please, do not speak of this again.
评论 #9247042 未加载
judk大约 10 年前
The terms are not precisely enough to give meaning to cross-language comparisons. Within a single language like C++, you can usefully differentiate the various ways to pass references and data.
评论 #9245407 未加载
moogly大约 10 年前
FWIW, in .NET land, we tend to say &quot;pass-by-reference-by-value&quot;.
评论 #9245349 未加载
评论 #9245371 未加载
knappador大约 10 年前
Novice Java programmer reads title, mutates Java object inside function, later notices side-effects, and curses author of the title.<p>Second novice Java programmer reads title, wants to pass objects into functions, wants to avoid expensive stack copy and writes &amp;myObject, gets compiler error, Googles &quot;Java pointer,&quot; and curses author of the title.<p>Lesson learned: author of title is either unaware of the consequences such an interpretation will cause or seeks cursing as a source of attention.
评论 #9247433 未加载
twic大约 10 年前
I remember this being a hot topic on usenet back in the &#x27;90s. It&#x27;s great to see it getting an outing today, and inciting equally as vigorous argument!
评论 #9246818 未加载
agricola大约 10 年前
I think people are reading way too much into what a reference is. In c++, it has a very specific meaning, but in Java it has a slightly different definition.<p>In c++, the only difference between a reference and a pointer is in the dereference syntax, and that a pointer can be reassigned. In the background, the variable is a pointer in both cases. It is simply syntactic sugar.<p>Another thing some people are mixing up is the entire philosophy between pass-by-reference and pass-by-value. The ability to write a simple swap function does not accurately demonstrate what a language is doing. It is quite simply whether or not the compiler creates a copy of the <i></i><i>object</i><i></i> (not a copy of the address &#x2F; pointer &#x2F; reference). If, in the background, Java passes an address &#x2F; pointer &#x2F; reference (the word makes absolutely no difference), when the programmer is attempting to pass an object, that is the definition of pass-by-reference regardless what arbitrary word I want to name the referencing value. Yes, the pointer is a copy of the previous pointer, but that&#x27;s not the explicit value that the programmer cares about.<p>Yet another comparison to c++: the same thing happens with pass-by-reference in c++. If a function has the prototype:<p><pre><code> void foo(Dog&amp; d); </code></pre> and I pass a Dog object in a call similar to:<p><pre><code> Dog d(&quot;Spot&quot;); foo(d); </code></pre> then, in the background, it is going create a reference (i.e. the address), and copy it on the stack. In my foo() function, the argument is simply already dereferenced (I don&#x27;t have to treat it like a pointer).<p>TLDR...<p>If you pass an object to a function, and operations performed by that function affect the original object, it is pass-by-reference. Period.
TazeTSchnitzel大约 10 年前
PHP unfortunately has the same issue because it copied Java&#x27;s terminology to describe object reference values (introduced in PHP 5), yet it has always also had &quot;references&quot; which are <i>actually</i> pass-by-reference.<p>To demonstrate, object references&#x2F;pointers&#x2F;whatever:<p><pre><code> $foo = new Foo(); &#x2F;&#x2F; $foo $foo2 = $foo; $foo2-&gt;x = 3; &#x2F;&#x2F; $foo-&gt;x is also 3 now, $foo and $foo2 point to the same Foo object &#x2F;&#x2F; that is, $foo and $foo2 both contain an object handle&#x2F;pointer&#x2F;reference&#x2F;whatever that points to the same Foo object </code></pre> PHP references:<p><pre><code> function swap(&amp;$a, &amp;$b) { $temp = $a; $a = $b; $b = $temp; } $a = 3; $b = 2; swap($a, $b); &#x2F;&#x2F; $a is now 2, $b is now 3</code></pre>
评论 #9245676 未加载
评论 #9245403 未加载
solipsism大约 10 年前
You can absolutely make a swap for reference types in Java. Here: <a href="https://gist.github.com/anonymous/d3b4b3bcacb478896ef2" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;anonymous&#x2F;d3b4b3bcacb478896ef2</a><p>This is analogous to a C++ swap(Type&amp;,Type&amp;). The main difference is that C++ provides a default assignment operator for types, meaning you don&#x27;t have to provide <i>Assign</i> yourself. A smaller difference is that the temporary instance can be created on the stack in C++ but not in Java.<p>For primitive types it&#x27;s absolutely true that you cannot implement swap (unless you were to have created that value type in a reference-type wrapper). It&#x27;s misleading to say you can&#x27;t do so for reference types.
评论 #9248590 未加载
diego898大约 10 年前
I asked a question some time ago on SO [1] where Scott Stanchfield - &quot;The Java Dude&quot; weighed in and it sparked quite a discussion. It is well worth reading the discussion there as well as this one.<p>[1] <a href="https://stackoverflow.com/questions/934775/changing-value-after-its-placed-in-hashmap-changes-whats-inside-hashmap" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;934775&#x2F;changing-value-af...</a>
city41大约 10 年前
I had a similar frustration over JavaScript recently and wrote a very similar post: <a href="http://www.mattgreer.org/articles/javascript-is-a-pass-by-value-language/" rel="nofollow">http:&#x2F;&#x2F;www.mattgreer.org&#x2F;articles&#x2F;javascript-is-a-pass-by-va...</a>
JBiserkov大约 10 年前
A pointer in Java<p><pre><code> Dog d; </code></pre> is exactly like C++&#x27;s<p><pre><code> Dog *d; </code></pre> Following a pointer and calling a method<p><pre><code> d.setName(&quot;Fifi&quot;); </code></pre> is exactly like C++&#x27;s<p><pre><code> d-&gt;setName(&quot;Fifi&quot;);</code></pre>
banachtarski大约 10 年前
The C++ implementation of swap given is wrong.<p>SomeType temp = arg1;<p>This would do a deep copy of the object pointed to by the ref arg1. What is intended is probably<p>SomeType&amp; temp = arg1;
评论 #9246785 未加载
moru0011大约 10 年前
if you want pass a reference to a reference do<p>Dog dog[] = { new Dog };<p>void method( Dog dog[] ) { dog[0] = new Dog(); }<p>Having this of side effect as a default would be an insane idea ofc., so I am not sure what you are complaining about :-)
评论 #9246594 未加载
Timono大约 10 年前
Java is Pass-By-Value for values and Pass-By-Copy-Reference for objects.
rspeer大约 10 年前
Dear author: webhostinggeeks did not actually translate your article into Serbo-Croatian for free. They just ran a shitty automatic translation and added in links that boost their black hat SEO empire.<p>They target many people who host highly linked articles this way. They picked Serbo-Croatian because you&#x27;re unlikely to verify it.<p>Do not post translations unless you trust the translator (perhaps because you paid them to do good work) or know the language.
miralabs大约 10 年前
<i>In short: Java has pointers and is strictly pass-by-value.</i><p>It&#x27;s a well know fact that Java has pointers given that you have NullPointerException as an exception.
评论 #9245344 未加载
评论 #9245503 未加载
anon4大约 10 年前
You absolutely CAN write swap in Java:<p><pre><code> void &lt;T&gt; swap(T a, T b) { &#x2F;&#x2F; use the Unsafe to copy a&#x27;s memory to a temp buffer &#x2F;&#x2F; then copy b&#x27;s memory to a &#x2F;&#x2F; then copy a&#x27;s memory to b &#x2F;&#x2F; Caution: Don&#x27;t pass Integers or anything, okay } </code></pre> Or, if the objects are Beans, just iterate the properties and swap them one by one. In fact, if you know you&#x27;re dealing with beans, the two don&#x27;t even have to be the same class, as long as their properties and types are the same.
评论 #9246304 未加载
评论 #9246297 未加载
lucio大约 10 年前
&gt;Java is strictly pass-by-value, exactly as in C<p>In C you can pass a pointer, and a pointer to a pointer. I understand both cases are usually called &quot;pass-by-reference&quot;. If you call &quot;pass-by-value&quot; to passing a pointer, then the notion of &quot;pass-by-value&quot; and &quot;pass-by-reference&quot; are not very useful.<p>IMHO &quot;pass-by-reference&quot; means you can mutate the attributes of the thing passed (as in java when you pass an object) and also means you can be operating on a &quot;volatile&quot; area of memory, meaning another thread can CHANGE the data while the function is executing.<p>OTOH &quot;pass-by-value&quot; means you get a &quot;snapshot&quot; of the value at the point of the function-call, the copy is normally on the stack, and no other thread will change the data while the function is running. Also you can mutate the area with gusto without worrying of data-races, side-effects or altering the calling function variables.<p>This two &quot;definitions&quot; of pass-by-value and pass-by-reference are the ones I find useful regarding concurrency and side-effects.<p>If you tell me that passing an integer and passing an object are both the same thing (pass-by-value) in Java, then I will tell you that pass-by-value and pass-by-reference are not very useful concepts.
评论 #9245348 未加载
评论 #9245323 未加载
评论 #9245343 未加载