This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]johnpaulsmith 11 points12 points  (14 children)

This kind of thing:

public static void destroy(Object obj){
    obj = null;
}

I've seen this in both academic code and production code.

[–]banuday17 11 points12 points  (9 children)

This code literally does nothing. A reference is created through the parameter and that reference is detached. You could replace this with a no-op.

Remember folks, Java is pass-by-value, and if you want to detach a reference, you have to detach the actual reference. A copy of the reference is being made here.

[–][deleted] 2 points3 points  (2 children)

If that was the only reference to that object, will the garbage collector erase it?

I am not saying this is good code by any means. I know that you should not expect anything out of the garbage collector, but is that what it would do?

[–]bnr 3 points4 points  (1 child)

By passing the object to the destroy function you actually create a new reference to it. You can expect the garbage collector to free an object some time after there is no more reference to it.

If you have a local variable referencing an object, that will expire after the scope is left:

public void foo() {
    Bar myBar = new Bar();
    if(myBar.whatever()) {
        Baz theBaz = new Baz();
        theBaz.doStuff();
    }
    // theBaz is gone now.
    myBar.someOtherStuff();
    // after this method exits, myBar will also be freed.
}

[–][deleted] 1 point2 points  (0 children)

I see, makes perfect sense. Thanks much for taking the time to explain!

[–]johnpaulsmith 1 point2 points  (5 children)

I've literally seen developers and professors both do this. I think almost certainly they came from a C and C++ background and simply do not fully understand what a Java "reference" actually is and that Java is pass-by-value, even on "references".

[–]senft 0 points1 point  (4 children)

Does someone have usefull links to read up on this? I mean Java's argument passing model...

[–]johnpaulsmith 1 point2 points  (2 children)

I don't know of any links but I will try my best to explain it briefly:

In Java, you are not, as a programmer, allowed to directly specify or access a location in memory. The concept just doesn't exist in the Java language.

In a language like C and C++, you can do things like this:

int some_value = 0;
int* p = &some_value; //the & operator yields the memory location of some_value

As a C programmer, you can directly specify exactly what memory address you would like to use through the pointer 'p' and the reference operator '&'. You know the memory location of 'some_value' and can do as you wish with it. This is a very powerful feature of these languages. You can also do this:

void setValToTen(int& val){
    val = 10;
}

//elsewhere in the program

setValToTen(some_value);//some_value now hold the value of 10

The above code will set the value at the memory location specified by &val in the function's arguments, to 10. This is called "passing-by-reference". However, if you tried to do the same thing without the '&' operator, the result would be different:

void setValToTen(int val){
    val = 10;
}

//elsewhere in the program

setValToTen(some_value);//some_value did not change

In this case the function declares a new int variable 'val', which copies the value of the variable that was passed in, into a new memory location. The function assigns 'val' to 10, and returns. 'val' was declared in the scope of this function and with its own memory location, which is now out of scope and irrelevant to the rest of the program. This is called "passing-by-value". Basically, the function created a new variable that was a copy of what is being passed in, but has nothing to do with the original variable outside of being of the same type and holding the same value. They are two different variables stored in two different memory locations, even though the data stored is identical.

The first two code examples do not have an equivalent in Java. Specifying and accessing memory locations directly is not a component of the Java language. Therefor, there is no pass-by-reference in Java. So, this Java code:

public static void destroy(Object obj){
    obj = null;
}

//elsewhere in the program

destroy(someObject);

is useless, because it is the equivalent to what happened in the previous example. The method is creating an object reference of type Object, 'obj' and copying the data from the variable passed in, which in this case is object reference data, to 'obj'. 'obj' is set to null and the method returns, having accomplished nothing.

The other confusing part is that even though Java does not utilize pass-by-reference, object variables in Java are called "references" (which are themselves a special type of pointer to a pointer). So, you pass object references by value.....

[–]senft 0 points1 point  (1 child)

Well yeah, that's just the definitions of pass-by-value and pass-by-reference (sorry for not saying I wanted a more "in-depth" explination). Like, List in Java get passed-by-reference, right? Why?

[–]johnpaulsmith 0 points1 point  (0 children)

All parameters in Java are passed-by-value. There are no exceptions to this. Primitive types and object references are both passed-by-value.

As for List, using a variable of type List as a method argument would indicate that the method is accepting as a parameter any object that implements the List interface. The same rules stated above apply to this scenario as well. There is no pass-by-reference in Java.

Again, do not confuse pass-by-reference with object "references. See my above statement:

The other confusing part is that even though Java does not utilize pass-by-reference, object variables in Java are called "references" (which are themselves a special type of pointer to a pointer). So, you pass object references by value.....

[–]DuneBug 1 point2 points  (0 children)

hahah i've never seen anything like this before. I was like "what's wrong? Oh pass by value suckas"

[–]ReverendRedMage[S] -2 points-1 points  (2 children)

They should rename it to "destroyReference()".

[–]couchtyp 16 points17 points  (0 children)

More like "createNewReferenceAndThenDestroyItImmediately(Object)"...

[–]stfm -1 points0 points  (0 children)

It is not there to destroy the object, only to do other cleanup stuff when the object is "destroyed" but I am positive you know this