What are the dos and don'ts while using references in Java?
Do you mean this? http://www.ibm.com/developerworks/library/j-refs/
If you mean the SoftReference, WeakReference and PhantomReferences:
Dos:
Use soft references to cache objects that are expensive in creation or memory wise. This will give your application a chance to remove objects before running out of memory, at the cost of a performance decrease.
Use WeakReferences when using the Observer pattern if you need to hold a reference to the class where you register your Observer. That guarantees that the listener won't prevent the parent from being garbage collected.
Don'ts:
Soft and weak referenced objects can be removed at any time, so never do:
if (reference.get() != null){
Object o = reference.get();
// Do something with o....
}
It might be the case that o receives a null pointer, as there is no guarantee when the garbage collector will be actived.
In short...
Java manipulates objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
So Objects can be passed into a method by referece, but primitives (int/boolean) are passed by value.
This site does a good job of explaining the differnces... Javaworld: pass by reference
The common problems that people who are new to Java have with understanding references are:
Confusion about Java's parameter passing mechanism. They think that because objects are references, that they are "passed by reference" in a method call. This is not true. Parameters are always "passed by value" in Java.
Confusion about what Java arrays are. Arrays are just a special kind of object. They are created on the heap, have references and those references are "passed by value" ... just like any other object.
Confusion about what
==
means for references. It means "is the same object as", not "is equal to". Theequals
method is for testing if two objects are equal ... whatever that means.A well-known subcase that new users frequently get wrong is when dealing with Strings, where it is common for two String objects to be "equal" but not "the same object". The simple rule is don't use
==
to compare strings.A less well-known subcase is with the primitive wrapper classes Boolean, Character, Integer and so on. The problem ... and solution ... is essentially the same as for strings; i.e. don't use
==
to compare instances of Boolean, Character, Integer and so on.Some people have problems with
null
. The basic concept is simple, but some people get into the bad habit of returningnull
when they should be throwing exceptions. And this leads to lots of unnecessary testing fornull
and flakiness due to unanticipatedNullPointerExceptions
when a necessary null test is left out.Some people think you should be able to create a reference for some object allocated on the stack. Java does not allow this. In Java, objects are always allocated in the heap. The stack frame contains only references and primitive values, and Java does not provide a way to "take the address of" anything.
Some people think you should be able to do pointer arithmetic with references. Java does not allow this.
But basically, Java references are really simple and easy to understand, and largely trouble free ... once you stop trying to think about them in terms of C / C++ pointers.
Most of the books, and article and even your test programs in this area may give you bad understanding something like (primitive types are always passed by value, and Objects and Arrays Always passed by reference) and if you tried this using basic test code like the following
public class Test {
public void changeArrayValues(String[] names) {
for(int i=0; i<names.length; i++)
names[i] += "_ALTERED";
}
public static void main(String[] args) {
String[] names = {"Cairo", "Alex", "Giza"};
for(int i=0; i<names.length; i++)
System.out.print(names[i] + ", ");
System.out.println();
new Test().changeArrayValues(names);
for(int i=0; i<names.length; i++)
System.out.print(names[i] + ", ");
}
}
you will get the following output:
Cairo, Alex, Giza, Cairo_ALTERED,
Alex_ALTERED, Giza_ALTERED
which will enforce the idea into your head.
but (primitive types are always passed by value, and Objects and Arrays Always passed by reference) is in correct. because in pass by reference you can move the reference to point to another object but in Java if you did this the referenced object will not feel with that change
try this
public class Test {
public void reIntializeArray(String[] names) {
names = new String[]{"X", "Y", "Z"};
}
public static void main(String[] args) {
String[] names = {"Cairo", "Alex", "Giza"};
for(int i=0; i<names.length; i++)
System.out.print(names[i] + ", ");
System.out.println();
new Test().reIntializeArray(names);
for(int i=0; i<names.length; i++)
System.out.print(names[i] + ", ");
}
}
and this will dump the following output:
Cairo, Alex, Giza,
Cairo, Alex, Giza,
so the array didn't get initialized with the new values as you see from the output.
so all pass in Java are pass by values
however you can benefit from the - first behavior - in altering the object content but you have to keep in mind that this is Java and not C++.