1

I have deep nested structures, and methods like "remove(<Something>)", "contains(<Something>)" etc. rely on access to the original reference in order to remove it etc. (a copy of the reference won't do).

How have people best worked around this so they can still conveniently add, remove, test for etc. the object they want, within different arbitrary methods and constructors etc., without adding any unnecessary complexity or any unnecessary loss in performance?

Navigateur
  • 1,368
  • 2
  • 17
  • 34
  • 1
    Could you clarify this a bit? Maybe give an example of the problem? Java passes anything apart from primitive types (int, char, boolean...) by reference. Only primitive types are passed by value. – G_H Aug 23 '11 at 13:55
  • 2
    @G_H that is WRONG WRONG WRONG. Java passes everything by value, period. – hvgotcodes Aug 23 '11 at 13:57
  • 2
    @G_H I am going to strongly disagree. Java passes everything by value. The thing that you call pass-by-reference is, in reality, pass-by-value of reference. – ZenMaster Aug 23 '11 at 13:58
  • Java passes the value of the reference ; ) – Shawn Aug 23 '11 at 13:59
  • Okay, okay. It's the value of a reference. Just depends on how you want to see it. At least we can all agree that you don't copy entire data structures when you pass stuff around, right? – G_H Aug 23 '11 at 14:03
  • 1
    no it doesn't. Passing references by value is PASS BY VALUE. just because java calls references references doesnt mean it uses pass by reference. If references in java were called hojongs java would not be pass by hojong. – hvgotcodes Aug 23 '11 at 14:12
  • Passing by reference means that you have the ability to change the value of the reference - something that has no effect in Java (when the reference exists the scope). – ZenMaster Aug 23 '11 at 14:19
  • That is assuming that a "reference" is a data structure of its own. Such as a pointer in C++ that contains a memory address. But if you've been always been programming in Java and are totally indoctrinated by it (like me), you think of that **value** as a reference. It's kind of semantics. But I agree with you all, when it comes to the actual details I've missed the ball. Blame my education :) I can't downvote my own comment, though. – G_H Aug 23 '11 at 14:38
  • I like to say that java is pass-by-copy-of-the-variable-value! For primitives, the variable-value is the primitive value itself; for objects, the variable-value is something that tells the JVM where to find the object in the Heap. Also, I believe that "Java" and "pointer" shouldn't even be written in the same page! ;) See: http://stackoverflow.com/questions/40480/is-java-pass-by-reference/7034719#7034719 – Marsellus Wallace Aug 23 '11 at 16:17

2 Answers2

3

Methods like remove and contains work fine with pass by value. The reason is that the even though the references are copied, they copy has the same value of the original. Just look at the Collections API. If you do something like (psuedocode)

List list = new List();
list.add(object1) // assume you have an object1 reference

and then you do

myRemove(list, object1);

both list and object 1 are passed by value, so in the myRemove method they are copies of the original reference. If in myRemove you do

list.remove(object1);

the object is still removed from the list no problem. Furthermore, since the list and object1 references in both scopes point to the same underlying objects, the list reference in the calling scope refers to the list that has the object removed.

The only time you would need pass by reference semantics is if you want to modify a reference in a method and have the modification apply in the scope that called the method.

So if you want to do

List myList = new List(); 
changeList(myList); 

and have changeList change where myList points in the calling scope, it wont work without some trickery. The trickery is called double indirection. Basically, you create an object that has an instance of what you want to be able to access with pass by reference semantics, and you pass the container object around.

So

class MyContainer {
    List list
}

now you can pass an instance of MyContainer into a method, and change the list value, and in the calling scope where the list points will be changed. Note that you are not doing anything special here, everything is still pass by value.

hvgotcodes
  • 109,621
  • 25
  • 195
  • 231
  • Do the reference copies produced by passing also conform to "`==`" equality with the original reference? In all cases? – Navigateur Aug 23 '11 at 17:15
  • if you're lazy you could just use a 1-element array instead of a custom container class – newacct Aug 24 '11 at 22:50
0

How have people best worked around this so...

By use of member fields (for working with references, not copies) and by use of inheritance and interfaces (for handling nested structures).

perissf
  • 15,117
  • 13
  • 73
  • 116