Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 2 years ago.
Arrays are not a primitive type in Java, but they are not objects either, so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?
Everything in Java is passed by value. In case of an array (which is nothing but an Object), the array reference is passed by value (just like an object reference is passed by value).
When you pass an array to other method, actually the reference to that array is copied.
Any changes in the content of array through that reference will affect the original array.
But changing the reference to point to a new array will not change the existing reference in original method.
See this post: Is Java "pass-by-reference" or "pass-by-value"?
See this working example:
public static void changeContent(int[] arr) {
// If we change the content of arr.
arr[0] = 10; // Will change the content of array in main()
}
public static void changeRef(int[] arr) {
// If we change the reference
arr = new int[2]; // Will not change the array in main()
arr[0] = 15;
}
public static void main(String[] args) {
int [] arr = new int[2];
arr[0] = 4;
arr[1] = 5;
changeContent(arr);
System.out.println(arr[0]); // Will print 10..
changeRef(arr);
System.out.println(arr[0]); // Will still print 10..
// Change the reference doesn't reflect change here..
}
Your question is based on a false premise.
Arrays are not a primitive type in Java, but they are not objects either ... "
In fact, all arrays in Java are objects1. Every Java array type has java.lang.Object as its supertype, and inherits the implementation of all methods in the Object API.
... so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?
Short answers: 1) pass by value, and 2) it makes no difference.
Longer answer:
Like all Java objects, arrays are passed by value ... but the value is the reference to the array. So, when you assign something to a cell of the array in the called method, you will be assigning to the same array object that the caller sees.
This is NOT pass-by-reference. Real pass-by-reference involves passing the address of a variable. With real pass-by-reference, the called method can assign to its local variable, and this causes the variable in the caller to be updated.
But not in Java. In Java, the called method can update the contents of the array, and it can update its copy of the array reference, but it can't update the variable in the caller that holds the caller's array reference. Hence ... what Java is providing is NOT pass-by-reference.
Here are some links that explain the difference between pass-by-reference and pass-by-value. If you don't understand my explanations above, or if you feel inclined to disagree with the terminology, you should read them.
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/cplr233.htm
http://www.cs.fsu.edu/~myers/c++/notes/references.html
Related SO question:
Is Java "pass-by-reference" or "pass-by-value"?
Historical background:
The phrase "pass-by-reference" was originally "call-by-reference", and it was used to distinguish the argument passing semantics of FORTRAN (call-by-reference) from those of ALGOL-60 (call-by-value and call-by-name).
In call-by-value, the argument expression is evaluated to a value, and that value is copied to the called method.
In call-by-reference, the argument expression is partially evaluated to an "lvalue" (i.e. the address of a variable or array element) that is passed to the calling method. The calling method can then directly read and update the variable / element.
In call-by-name, the actual argument expression is passed to the calling method (!!) which can evaluate it multiple times (!!!). This was complicated to implement, and could be used (abused) to write code that was very difficult to understand. Call-by-name was only ever used in Algol-60 (thankfully!).
UPDATE
Actually, Algol-60's call-by-name is similar to passing lambda expressions as parameters. The wrinkle is that these not-exactly-lambda-expressions (they were referred to as "thunks" at the implementation level) can indirectly modify the state of variables that are in scope in the calling procedure / function. That is part of what made them so hard to understand. (See the Wikipedia page on Jensen's Device for example.)
1. Nothing in the linked Q&A (Arrays in Java and how they are stored in memory) either states or implies that arrays are not objects.
Arrays are in fact objects, so a reference is passed (the reference itself is passed by value, confused yet?). Quick example:
// assuming you allocated the list
public void addItem(Integer[] list, int item) {
list[1] = item;
}
You will see the changes to the list from the calling code. However you can't change the reference itself, since it's passed by value:
// assuming you allocated the list
public void changeArray(Integer[] list) {
list = null;
}
If you pass a non-null list, it won't be null by the time the method returns.
No that is wrong. Arrays are special objects in Java. So it is like passing other objects where you pass the value of the reference, but not the reference itself. Meaning, changing the reference of an array in the called routine will not be reflected in the calling routine.
Everything in Java is passed by value .
In the case of the array the reference is copied into a new reference, but remember that everything in Java is passed by value .
Take a look at this interesting article for further information ...
The definitive discussion of arrays is at http://docs.oracle.com/javase/specs/jls/se5.0/html/arrays.html#27803 . This makes clear that Java arrays are objects. The class of these objects is defined in 10.8.
Section 8.4.1 of the language spec, http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#40420 , describe how arguments are passed to methods. Since Java syntax is derived from C and C++, the behavior is similar. Primitive types are passed by value, as with C. When an object is passed, an object reference (pointer) is passed by value, mirroring the C syntax of passing a pointer by value. See 4.3.1, http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.3 ,
In practical terms, this means that modifying the contents of an array within a method is reflected in the array object in the calling scope, but reassigning a new value to the reference within the method has no effect on the reference in the calling scope, which is exactly the behavior you would expect of a pointer to a struct in C or an object in C++.
At least part of the confusion in terminology stems from the history of high level languages prior to the common use of C. In prior, popular, high level languages, directly referencing memory by address was something to be avoided to the extent possible, and it was considered the job of the language to provide a layer of abstraction. This made it necessary for the language to explicitly support a mechanism for returning values from subroutines (not necessarily functions). This mechanism is what is formally meant when referring to 'pass by reference'.
When C was introduced, it came with a stripped down notion of procedure calling, where all arguments are input-only, and the only value returned to the caller is a function result. However, the purpose of passing references could be achieved through the explicit and broad use of pointers. Since it serves the same purpose, the practice of passing a pointer as a reference to a value is often colloquially referred to a passing by reference. If the semantics of a routine call for a parameter to be passed by reference, the syntax of C requires the programmer to explicitly pass a pointer. Passing a pointer by value is the design pattern for implementing pass by reference semantics in C.
Since it can often seem like the sole purpose of raw pointers in C is to create crashing bugs, subsequent developments, especially Java, have sought to return to safer means to pass parameters. However, the dominance of C made it incumbent on the developers to mimic the familiar style of C coding. The result is references that are passed similarly to pointers, but are implemented with more protections to make them safer. An alternative would have been the rich syntax of a language like Ada, but this would have presented the appearance of an unwelcome learning curve, and lessened the likely adoption of Java.
In short, the design of parameter passing for objects, including arrays, in Java,is esentially to serve the semantic intent of pass by reference, but is imlemented with the syntax of passing a reference by value.
Kind of a trick realty... Even references are passed by value in Java, hence a change to the reference itself being scoped at the called function level. The compiler and/or JVM will often turn a value type into a reference.
I have a rather simple question with an inkling as to what the answer is.
My generalized question:
What is actually going on when you declare a member variable, be it public or private, and for all permutations of variable types, e.g. static vs const vs regular variables?
class some_class
{
private:
static const std::string str;
public:
...
}
I have kind of realized that in C++ there is no notion of a non-variable, that is, a non-constructed variable as I was kind of taught to believe exists with languages like Java. The same may also be true in Java, however it is not the way I was taught to think of things so I'm trying to come up with the correct way to think of these non-initialized variables.
public class main {
public static void main(String[] args) {
String str; // A kind of non-variable, or non-constructed variable (refers to null).
str = new String(); // Now this variable actually refers to an object rather than null, it is a constructed variable.
}
}
Since C++ allows you to initialize member variables in the constructor through initializer lists, and I have proven to myself via use of a debugger that the variable doesn't exist before it is initialized through the initializer list (either explicitly or by default), what is, then, actually going on behind the scenes when you declare the member variable?
Tricky question -- it's ambiguous depending on perspective.
From a pseudo-machine perspective, normally adding a non-static plain old data type to a class makes that class type bigger. The compiler also figures out how to align it and relative memory offsets to address it relative to the object in the resulting machine code.
This is pseudo-machine level because at the machine level, data types don't actually exist: just raw bits and bytes, registers, instructions, things like that.
When you add a non-primitive user-defined type, this recurses and the compiler generates the instructions to access the members of the member and so on.
From a higher level, adding members to a class makes the member accessible from instances (objects) of the class. The constructor initializes those members, and the destructor destroys them (recursively triggering destructors of members that have non-trivial destructors, and likewise for constructors in the construction phase).
Yet your example is a static member. For static members, they get stored in a data segment at the machine level and the compiler generates the code to access those static members from the data segment.
Some of this might be a bit confusing. C++ shares its legacy with C which is a hardware-level language, and its static compilation and linking affects its design. So while it can go pretty high-level, a lot of its constructs are still tied to how the hardware, compiler, and linker does things, whereas in Java, the language can make some more sensible choices in favor of programmer convenience without a language design that somewhat reflects all of these things.
Yes and no.
A variable of class type in Java is really a pointer. Unlike C and C++ pointers, it doesn't support pointer arithmetic (but that's not essential to being a pointer--for example, pointers in Pascal didn't support arithmetic either).
So, when you define a variable of class type in Java: String str;, it's pretty much equivalent to defining a pointer in C++: String *str;. You can then assign a new (or existing) String object to that, as you've shown.
Now, it's certainly possible to achieve roughly the same effect in C++ by explicitly using a pointer (or reference). There are differences though. If you use a pointer, you have to explicitly dereference that pointer to get the object to which it refers. If you use a reference, you must initialize the reference--and once you do so, that reference can never refer to any object other than the one with which it was initialized.
There are also some special rules for const variables in C++. In many cases, where you're just defining a symbolic name for a value:
static const int size = 1234;
...and you never use that variable in a way that requires it to have an address (e.g., taking its address), it usually won't be assigned an address at all. In other words, the compiler will know the value you've associated with that name, but when compilation is finished, the compiler will have substituted the value anywhere you've used that name, so the variable (as such) basically disappears (though if you have the compiler generate debugging information, it'll usually retain enough to know and display its name/type correctly).
C++ does have one other case where a variable is a little like a Java "zombie" object that's been declared but not initialized. If you move from an object: object x = std::move(y);, after the move is complete the source of the move (y in this case) can be in a rather strange state where it exists, but about all you can really do with it is assign a new value to it. Just for example, in the case of a string, it might be an empty string--but it also could retain exactly the value it had before the move, or it could contain some other value (e.g., the value that the destination string held before the move).
Even that, however, is a little bit different--even though you don't know its state, it's still an object that should maintain the invariants of its class--for example, if you move from a string, and then ask for the string's length, that length should match up with what the string actually contains--if (for example) you print it out, you don't know what string will print out, but you should not get an equivalent of a NullPointerException--if it's an empty string, it just won't print anything out. If it's a non-empty string, the length of the data that's printed out should match up with what its .size() indicates, and so on.
The other obviously similar C++ type would be a pointer. An uninitialized pointer does not point to an object. The pointer itself exists though--it just doesn't refer to anything. Attempting to dereference it could give some sort of error message telling you that you've attempted to use a null pointer--but unless it has static storage duration, or you've explicitly initialized it, there's no guarantee that it'll be a null pointer either--attempting to dereference it could give a garbage value, throw an exception, or almost anything else (i.e., it's undefined behavior).
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
I’ve read a lot of articles about how “pass-by-reference” doesn’t exist in Java since a copy of the value of the reference is passed, hence “pass-by-copy-of-reference-value”.
The articles also say a reference value is a pointer.
(So pointers do exist in Java.)
Some other articles say: Java has no pointers.
So what is the correct solution?
How does a pointer differ from a reference (or reference value), and do they exist in Java?
They aren't like C pointers. There's no pointer arithmetic allowed.
Java has only one mechanism for passing parameters: pass by value in all cases. For primitives, the value is passed. For objects, the reference to the object on the heap is passed.
A pointer is a reference type; it refers to something. What you're basically asking is: "Does Java have Dobermans? Because some articles say it has dogs."
As noted in Wikipedia entry for Pointer:
A pointer is a simple, more concrete implementation of the more abstract reference data type. Several languages support some type of pointer, although some have more restrictions on their use than others
It goes on to say this about Java specifically:
Unlike C, C++, or Pascal, there is no explicit representation of pointers in Java. Instead, more complex data structures like objects and arrays are implemented using references. The language does not provide any explicit pointer manipulation operators. It is still possible for code to attempt to dereference a null reference (null pointer), however, which results in a run-time exception being thrown. The space occupied by unreferenced memory objects is recovered automatically by garbage collection at run-time.
Looking up Reference you find:
In computer science, a reference is a value that enables a program to indirectly access a particular datum, such as a variable or a record, in the computer's memory or in some other storage device. The reference is said to refer to the datum, and accessing the datum is called dereferencing the reference.
A reference is distinct from the data itself. Typically, a reference is the physical address of where the data is stored in memory or in the storage device. For this reason, a reference is often called a pointer or address, and is said to point to the data. However a reference may also be the offset (difference) between the datum's address and some fixed "base" address, or an index into an array.
Java chose to use the broader term "reference" instead of "pointer" because of the differences between Java and C. (Thus creating a sisyphus-like situation where we have to keep explaining that Java is pass-by-value).
You don't have a C pointer, you have a Java Reference. This has nothing to do with a C++ reference, or pass-by-reference.
Because Java is pass-by-value it is similar to using a C pointer in that when you pass it to a method, the value (e.g. memory address) is copied.
It is right to say both:)
Java has no pointers since java has simplified pointers as references.
Object o=new Object();
We got an object o here; o is actually a pointer.
Basically, pointers and references are the same thing; they point to (refer to) something else in memory. However, you cannot do integer arithmetic on references. You may find some pages on this slide useful:
http://www.cis.upenn.edu/~matuszek/cit594-2005/Lectures/15-pointers-and-references.ppt
You have to get your head around the different, but related concepts of types, variables and objects. If we ignore for now the fundamental types like int and only consider class types, then in Java there are variables, which are "named things", and objects. Both variables and objects have a type. However, a variable of type T is not an object; rather, it is a mechanism for locating an object of type T, and for informing the runtime that this object is in use. A variable may at any point not locate any object, in which case it is null, or it may, and in that case the very existence of the variable keeps the object alive.
Let's repeat: Variables have names. Objects don't have names. Variables are not objects.
When you pass a variable as an argument into a function call, the corresponding function parameter becomes duplicate of the argument, so that there are now two variables which both locate the same object. When you assign one variable to another, you make the left-hand variable locate the same object (possibly null) as the right-hand variable, relinquishing the possibly previously held location. But no objects are being affected by this; the objects exist in some unrelated, unprobable plane of existence.
Also, variables have a deterministic lifetime, which is determined by their scope (essentially block-local or static-global). The lifetime of variables is non-deterministically related to the lifetime of objects, but the lifetime of objects cannot be controlled directly.
That's the type system and object model of Java (for class types) in a nutshell. It's up to you what you want to label this; it makes sense to say that "variables are references", since that's what they do, but you might as well just stop trying to compare yourself to other languages and just say "variables", which is clear enough within the context of Java. Variables are variables, objects are objects, neither one is ever the other, and you need the former to talk about the latter.
In Java, a reference is a pointer, usually one that isn't null. That's why it's called NullPointerException, not NullReferenceException. "The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object. "
Java pointers/references are akin to Pascal pointers, not to C or C++ pointers, in that they are very strongly typed and do not support address arithmetic.
The error I get from the compiler is "The left hand side of an assignment must be a variable". My use case is deep copying, but is not really relevant.
In C++, one can assign to *this.
The question is not how to circumvent assignment to this. It's very simple, but rather what rationale is there behind the decision not to make this a variable.
Are the reasons technical or conceptual?
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
Please restrain from variations of "because java specs say so". I would like to know the reason for the decision.
In C++, one can assign to *this
Yes, but you can't do this = something in C++, which I actually believe is a closer match for what you're asking about on the Java side here.
[...] what rationale is there behind the decision not to make this a variable.
I would say clarity / readability.
this was chosen to be a reserved word, probably since it's not passed as an explicit argument to a method. Using it as an ordinary parameter and being able to reassign a new value to it, would mess up readability severely.
In fact, many people argue that you shouldn't change argument-variables at all, for this very reason.
Are the reasons technical or conceptual?
Mostly conceptual I would presume. A few technical quirks would arise though. If you could reassign a value to this, you could completely hide instance variables behind local variables for example.
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
I'm not sure I understand this statement fully, but yes, error prone is probably the primary reason behind the decision to make it a keyword and not a variable.
because this is final,
this is keyword, not a variable. and you can't assign something to keyword. now for a min consider if it were a reference variable in design spec..and see the example below
and it holds implicit reference to the object calling method. and it is used for reference purpose only, now consider you assign something to this so won't it break everything ?
Example
consider the following code from String class (Note: below code contains compilation error it is just to demonstrate OP the situation)
public CharSequence subSequence(int beginIndex, int endIndex) {
//if you assign something here
this = "XYZ" ;
// you can imagine the zoombie situation here
return this.substring(beginIndex, endIndex);
}
Are the reasons technical or conceptual?
IMO, conceptual.
The this keyword is a short hand for "the reference to the object whose method you are currently executing". You can't change what that object is. It simply makes no sense in the Java execution model.
Since it makes no sense for this to change, there is no sense in making it a variable.
(Note that in C++ you are assigning to *this, not this. And in Java there is no * operator and no real equivalent to it.)
If you take the view that you could change the target object for a method in mid flight, then here are some counter questions.
What is the use of doing this? What problems would this (hypothetical) linguistic feature help you solve ... that can't be solved in a more easy-to-understand way?
How would you deal with mutexes? For instance, what would happen if you assign to this in the middle of a synchronized method ... and does the proposed semantic make sense? (The problem is that you either end up executing in synchronized method on an object that you don't have a lock on ... or you have to unlock the old this and lock the new this with the complications that that entails. And besides, how does this make sense in terms of what mutexes are designed to achieve?)
How would you make sense of something like this:
class Animal {
foo(Animal other) {
this = other;
// At this point we could be executing the overridden
// Animal version of the foo method ... on a Llama.
}
}
class Llama {
foo(Animal other) {
}
}
Sure you can ascribe a semantic to this but:
you've broken encapsulation of the subclass in a way that is hard to understand, and
you've not actually achieved anything particularly useful.
If you try seriously to answer these questions, I expect you'll come to the conclusion that it would have been a bad idea to implement this. (But if you do have satisfactory answers, I'd encourage you to write them up and post them as your own Answer to your Question!)
But in reality, I doubt that the Java designers even gave this idea more than a moment's consideration. (And rightly so, IMO)
The *this = ... form of C++ is really just a shorthand for a sequence of assignments of the the attributes of the current object. We can already do that in Java ... with a sequence of normal assignments. There is certainly no need for new syntax to support this. (How often does a class reinitialize itself from the state of another class?)
I note that you commented thus:
I wonder what the semantics of this = xy; should be. What do you think it should do? – JimmyB Nov 2 '11 at 12:18
Provided xy is of the right type, the reference of this would be set to xy, making the "original" object gc-eligible - kostja Nov 2 '11 at 12:24
That won't work.
The value of this is (effectively) passed by value to the method when the method is invoked. The callee doesn't know where the this reference came from.
Even if it did, that's only one place where the reference is held. Unless null is assigned in all places, the object cannot be eligible of garbage collection.
Ignoring the fact that this is technically impossible, I do not think that your idea would be useful OR conducive to writing readable / maintainable code. Consider this:
public class MyClass {
public void kill(MyClass other) {
this = other;
}
}
MyClass mine = new MyClass();
....
mine.kill(new MyClass());
// 'mine' is now null!
Why would you want to do that? Supposing that the method name was something innocuous rather than kill, would you expect the method to be able to zap the value of mine?
I don't. In fact, I think that this would be a misfeature: useless and dangerous.
Even without these nasty "make it unreachable" semantics, I don't actually see any good use-cases for modifying this.
this isn't even a variable. It's a keyword, as defined in the Java Language Specification:
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed
So, it's not possible as it's not possible to assign a value to while.
The this in Java is a part of the language, a key word, not a simple variable. It was made for accessing an object from one of its methods, not another object. Assigning another object to it would cause a mess. If you want to save another objects reference in your object, just create a new variable.
The reason is just conceptual. this was made for accessing an Object itself, for example to return it in a method. Like I said, it would cause a mess if you would assign another reference to it. Tell me a reason why altering this would make sense.
Assigning to (*this) in C++ performs a copy operation -- treating the object as a value-type.
Java does not use the concept of a value-type for classes. Object assignment is always by-reference.
To copy an object as if it were a value-type: How do I copy an object in Java?
The terminology used for Java is confusing though: Is Java “pass-by-reference” or “pass-by-value”
Answer: Java passes references by value. (from here)
In other words, because Java never treats non-primitives as value-types, every class-type variable is a reference (effectively a pointer).
So when I say, "object assignment is always by-reference", it might be more technically accurate to phrase that as "object assignment is always by the value of the reference".
The practical implication of the distinction drawn by Java always being pass-by-value is embodied in the question "How do I make my swap function in java?", and its answer: You can't. Languages such as C and C++ are able to provide swap functions because they, unlike Java, allow you to assign from any variable by using a reference to that variable -- thus allowing you to change its value (if non-const) without changing the contents of the object that it previously referenced.
It could make your head spin to try to think this all the way through, but here goes nothing...
Java class-type variables are always "references" which are effectively pointers.
Java pointers are primitive types.
Java assignment is always by the value of the underlying primitive (the pointer in this case).
Java simply has no mechanism equivalent to C/C++ pass-by-reference that would allow you to indirectly modify a free-standing primitive type, which may be a "pointer" such as this.
Additionally, it is interesting to note that C++ actually has two different syntaxes for pass-by-reference. One is based on explicit pointers, and was inherited from the C language. The other is based on the C++ reference-type operator &. [There is also the C++ smart pointer form of reference management, but that is more akin to Java-like semantics -- where the references themselves are passed by value.]
Note: In the above discussion assign-by and pass-by are generally interchangeable terminology. Underlying any assignment, is a conceptual operator function that performs the assignment based on the right-hand-side object being passed in.
So coming back to the original question: If you could assign to this in Java, that would imply changing the value of the reference held by this. That is actually equivalent to assigning directly to this in C++, which is not legal in that language either.
In both Java and C++, this is effectively a pointer that cannot be modified. Java seems different because it uses the . operator to dereference the pointer -- which, if you're used to C++ syntax, gives you the impression that it isn't one.
You can, of course, write something in Java that is similar to a C++ copy constructor, but unlike with C++, there is no way of getting around the fact that the implementation will need to be supplied in terms of an explicit member-wise initialization. [In C++ you can avoid this, ultimately, only because the compiler will provide a member-wise implementation of the assignment operator for you.]
The Java limitation that you can't copy to this as a whole is sort-of artificial though. You can achieve exactly the same result by writing it out member-wise, but the language just doesn't have a natural way of specifying such an operation to be performed on a this -- the C++ syntax, (*this) doesn't have an analogue in Java.
And, in fact, there is no built-in operation in Java that reassigns the contents of any existing object -- even if it's not referred to as this. [Such an operation is probably more important for stack-based objects such as are common in C++.]
Regarding the use-case of performing a deep copy: It's complicated in Java.
For C++, a value-type-oriented language. The semantic intention of assignment is generally obvious. If I say a=b, I typically want a to become and independent clone of b, containing an equal value. C++ does this automatically for assignment, and there are plans to automate the process, also, for the comparison.
For Java, and other reference-oriented languages, copying an object, in a generic sense, has ambiguous meaning. Primitives aside, Java doesn't differentiate between value-types and reference-types, so copying an object has to consider every nested class-type member (including those of the parent) and decide, on a case-by-case basis, if that member object should be copied or just referenced. If left to default implementations, there is a very good chance that result would not be what you want.
Comparing objects for equality in Java suffers from the same ambiguities.
Based on all of this, the answer to the underlying question: why can't I copy an object by some simple, automatically generated, operation on this, is that fundamentally, Java doesn't have a clear notion of what it means to copy an object.
One last point, to answer the literal question:
What rationale is there behind the decision not to make this a variable?
It would simply be pointless to do so. The value of this is just a pointer that has been passed to a function, and if you were able to change the value of this, it could not directly affect whatever object, or reference, was used to invoke that method. After all, Java is pass-by-value.
Assigning to *this in C++ isn't equivalent to assigning this in Java. Assigning this is, and it isn't legal in either language.
Let's say for example I have a class A that creates an instance of a fairly big object B. Is passing B as a parameter to a method in a class C inefficient? That is, does it just pass a reference or does it shift the object's memory around as well?
Thanks.
It just passes a reference. It's important to understand that the value of any expression in Java is never an object. It's only ever a reference or a primitive value.
This isn't just relevant for parameter passing - it's important to understand for return types, arrays, simple assignment etc.
Java can only pass two kinds of values to a method:
primitive values (int, char, double, ...) or
object references
There is no way you can pass a whole object "by value".
This means that you don't need to worry about "how big" your object is that you "pass around".
It's not inefficient, because only the object reference is passed to the method.
As long as your calls are local (same JVM) object size should not matter, however when your application uses remote calls like RMI / Web Service (across JVMs) the large objects are capable of slowing down your application to a great extent because of huge amount of data that will be marshalled / unmarshalled and the network latency involved for every remote call.
As others have said, in Java you only have pass-by-value. These values are only primitives and references. The largest a primitive or reference can be is 8-bytes. IMHO, there is no such thing as a large argument.
There is nothing like memory Shifting.. it just passes the actual reference.. and the reference word itself stands for some address.. so no issue.. its efficient than parameter passing which really makes code more complex.. may be thats why SUN added it to java...
It just pass a reference as value.
Java passes references to objects by value. It makes no difference performance-wise whether the object reference being passed to C is big or not.