Quick answer: what gets passed to your functions cookEggs
and cookOne
are references to the objects, not to the variables (which would be real pass-by-reference).
The term pass-by-reference is often misused to mean pass-references-by-value: many languages only have pass-by-value semantics, where the values that are passed around are references (i.e. pointers, without the dangerous features). See Is Java "pass-by-reference" or "pass-by-value"?
In the case of cookEggs(eggList)
…
…the variable eggList
contains a reference to a list of eggs. That reference was initially given to you by the expression new List()
, and you're passing it to cookEggs
after storing meanwhile in your variable eggList
. Inside cookEggs
, adding to the list works, because you passed a reference to an actual, existing list object.
In the case of cookOne(single)
…
…the variable single
has only been declared, so it was implicitly initialized by the language runtime to the special reference null
. Inside cookOne
, you're replacing which reference is contained in egg
; since single
is a different variable, it still contains null
, therefore the code fails when you try to use that.
To clarify
The pass-references-by-value behavior is common to a lot of modern languages (Smalltalk, Java, Ruby, Python…). When you pass an object, you're actually passing-by-value (therefore copying) the contents of your variable, which is a pointer to the object. You never control where objects really exist.
Those pointers are named references rather than pointers, because they are restricted to abstract away the memory layout: you can't know the address of an object, you can't peek at the bytes around an object, you can't even be sure that an object is stored at a fixed place in memory, or that it's stored in memory at all (one could implement object references as UUIDs or keys in a persistent database, as in Gemstone).
In contrast, with pass-by-reference, you'd conceptually pass the variable itself, not its contents. To implement pass-by-reference in a pass-by-value language, you would need to reify variables as ValueHolder objects that can be passed around and whose contents can be changed.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…