Leo Aso
Leo Aso

Reputation: 12503

Pointer Logic in Java

I need to find a way to directly modify the private members of a class in Java through a getter function. I know I can do this in C++ using pointers like this;

class FooBar
{
    private:
        Foo foo;

    public:
        Foo* getFoo()
        {
            return &foo;
        }
}

Then I could directly manipulate the private variable foo through the public function getFoo() because getFoo() returns a pointer (eg. getFoo()->callFunction();)

So all I want to know is, is there a way to replicate this exact same effect in Java??.... Any way at all?

Upvotes: 0

Views: 407

Answers (7)

wulfgarpro
wulfgarpro

Reputation: 6934

Java is Pass by Value, or more specifically, Pass a Reference by Value. This means all reference types are passed around such that:

List<String> a = myObj.getList();
a.add("My String"); // this modifies the source list

List<String> b = new ArrayList<String>();
a = b; // this doesn't change the source list's reference

When programming in Java, most people try and achieve the highest level of encapsulation possible, converting mutable types into immutable types (e.g. using copy constructor idiom). This is a good way to program in the OOP space.

If you don't have a setter, you might want to use Java's built in reflection:

public class Test {
    private String NAME = "OLD NAME";

    public String getName() {
        return this.NAME;
    }

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Test t = new Test();
        System.out.println(t.getName()); // OLD NAME

        Field f = t.getClass().getDeclaredField("NAME");
        f.setAccessible(true); // allows access to private field 
        f.set(t, "NEW NAME");

        System.out.println(t.getName()); // NEW NAME
    }
}

But beware, reflection is an advanced topic, and in most cases a symptom of bad programming.

Upvotes: 0

SylvainL
SylvainL

Reputation: 3938

Even in C++ this is a bad idea, because if the object becomes deallocated, your pointer will now point toward an invalid memory location. This is one of the reasons why you don't have pointer in Java; in order to protect the memory to be accessed from rogue pointers. Therefore, in Java, all the accesses to a private field must be made through the enclosing object itself, usually with a get/set combination.

However, I suppose that using a set() is not the solution that you want; possibly because you have a collection of objects from different classes who don't share a common hierarchy other than Object. If this is the case, then a potential solution would be to create and use a common interface. This way, you can use this common interface to store a reference for these different objects and manipulate them in the same common way; for example:

static void test() {

    List<IntegerGetSet> list = new ArrayList<IntegerGetSet>();
    list.add (new A1(1));
    list.add (new B1(2));

    for (IntegerGetSet igs: list) {
        igs.set (igs.get() * 10);               
        System.out.println(igs.get()); 
    }
}

interface IntegerGetSet {   
    public int get();
    public void set (int i);
}

static class A1 implements IntegerGetSet {

    private int i;

    public A1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

static class B1 implements IntegerGetSet {
    private int i;

    public B1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

If you cannot modify those classes, then you will have something more complicated to cook up; for example by using Reflection as suggested in another post.

Upvotes: 0

Alex Oreshkevich
Alex Oreshkevich

Reputation: 21

What do you need can be accessed throught simply getter as was already shown. Some significant details:

if you wanna somethink like

getFoo()->callFunction();

be sure that:

  • Foo class is visible (default modifier if you are in the same package, protected if caller is subclass or public otherwise)
  • callFunction() is a visible (same rules)

if you wanna somethink like

getFoo().value = newValue;

be sure that value is modifiable, that means that class Foo does NOT defines value as final:

class Foo {
    // in this case value is immutable
    final Bar value;
}

In the last case compiler would say to you, that "The final field Foo.value cannot be assigned".

Upvotes: 1

Ravi
Ravi

Reputation: 31417

Since, Java doesn't have Pointer. But, you can do this, using getter and setter, it will help you like this

class myclass{
private myclass val;  // private field

//get the private field
public myclass getVal(){
return val;
}

//set/change the member field value
public void setVal(myclass val){
this.val=val;
}

}

Upvotes: 2

akuhn
akuhn

Reputation: 27813

You must provide a getter and a setter

class FooBar {

    private Foo foo;

    public Foo getFoo() {
        return foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }

}

Upvotes: 1

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29233

class FooBar {
    private Foo foo;

    public Foo getFoo() {
        return foo;
    }
}

All object variables in Java are references to an object, so you can think of them as "locked" pointers. "Locked" in the sense that you can't do any pointer arithmetic with it.

Upvotes: 5

Scorpion
Scorpion

Reputation: 3986

In java your getter returns a reference to the object so you could rely on public methods of the returned object to mofify it. I can elaborate further if you detail what you want to do. As an example,

If a getter returns a list, it would be possible for callers to modify the list using add or remove methods.

Upvotes: 2

Related Questions