I recently wrote this little program, maybe it can help explain what’s going on:
class Test {
// private might be misleading, as
// we could change the content of p
// by calling getPos()
private PVector p;
Test(float x, float y) {
p = new PVector(x, y);
}
// other languages have ways to specify that
// the returned value can not be modified,
// but that doesn't exist in Java (afaik), therefore
// the returned object CAN be changed.
public PVector getPos() {
return p;
}
// in Java we can return a copy. Which is less
// efficient, specially if the returned object is
// heavy. But at least by doing this we make sure
// the variable (p in this case) is not modified
// from outside, which might lead to unpredictable results
public PVector getPosCopy() {
return p.copy();
}
public void print() {
println(p);
}
}
void setup() {
Test t = new Test(4, 6);
t.print(); // [ 4.0, 6.0, 0.0 ]
// here we change p even if it's private
t.getPos().x = 6;
t.print(); // [ 6.0, 6.0, 0.0 ]
// here we only get a copy, so we don't
// change the original
t.getPosCopy().x = 666;
t.print(); // [ 6.0, 6.0, 0.0 ]
}
// The program above includes both getPos() and getPosCopy()
// to show their difference.
// In a proper program you may want just one of the two.
It’s not black magic It’s also not pointers (there’s no pointer arithmetic in Java), but references. I agree it can be surprising when you encounter it for the first time.