As has been already pointed out in the comments, your attempt will fail because Integer objects are immutable. I would still like to post an answer for non-immutable objects, which will point out the key difference to C++ pointers.
Short answer to your first question: For a "normal" (non-immutable) object it will have a similiar functionality but not exactly the same.
In Java, functions receive a copy of the reference to an object. Strictly speaking this makes it pass-by-value. The following example shall demonstrate the key differences to C++ pointers.
public class Main {
public static class Test {
public String text;
public Test(String text) {
this.text = text;
}
public void doit() {
System.out.println(text);
}
}
static void reference() {
Test[] t = {new Test("This is class 0"), new Test("This is class 1")};
attemptSwitch(t[0], t[1]);
System.out.println();
System.out.println("calling t[0].doit() outside attemptSwitch():");
t[0].doit();
System.out.println("calling t[1].doit() outside attemptSwitch():");
t[1].doit();
manipulate(t[0]);
manipulate(t[1]);
System.out.println();
System.out.println("calling t[0].doit() after manipulate()");
t[0].doit();
System.out.println("calling t[1].doit() after manipulate()");
t[1].doit();
}
static void attemptSwitch(Test t0, Test t1) {
Test tmp = t0;
t0 = t1;
t1 = tmp;
System.out.println("calling t0.doit() from inside attemptSwitch():");
t0.doit();
System.out.println("calling t1.doit() from inside attemptSwitch():");
t1.doit();
return;
}
public static void manipulate(Test t) {
t.text = "This class has been manipulated!";
}
}
The above class will first create an array with two Test
objects.
Then it will attempt to switch those objects in attemptSwitch()
and after that it will try to change the content of text
by calling mainpulate()
.
The output will look like this:
calling t0.doit() from inside attemptSwitch():
This is class 1
calling t1.doit() from inside attemptSwitch():
This is class 0
calling t[0].doit() outside attemptSwitch():
This is class 0
calling t[1].doit() outside attemptSwitch():
This is class 1
calling t[0].doit() after manipulate()
This class has been manipulated!
calling t[1].doit() after manipulate()
This class has been manipulated!
As you can see, the switch is successful inside attemptSwitch()
, but this switch is not persistent. Outside of the function attemptSwitch()
the references were not affected at all and the Test
objects were not switched.
This is due to the fact, that attemptSwitch()
received only a copy of the references to our Test
objects. Only those copies were switched inside the function.
As the call to manipulate()
shows, it is possible to persistently alter the contents of a class. In this case, it does not matter that the function receives just a copy of the reference, since it also points to the same address where the class stores its contents.
As for your second question, I have used similiar constructs. This approach is probably more prone to produce a memory leak, i.e., keep an object longer in memory than required, than losing data. As long as there is at least one reference pointing to your object it will not get garbage collected - if the reference is not a weak reference or something similiar. AFAIK, PriorityQueue uses regular references.