1

I have the following code:

Example is a class that I have no access to, and has Object original as an instance variable.

public class Example {

    private Object original;

    public Object getOriginal() {
        return original;
    {
}

changePointer(Object param) is a method that could be in any arbitrary static helper class (IE, Math).

public static void changePointer(Object param) {
    //Change the pointer of original
}

I want changePointer(Object o) to be able to change the pointer of original.

The transformation must be done in changePointer(Object param). IE, the following isn't useful to me:

public static void exampleMethod() {
    Object original = new Object();
    original = changePointer(original);
}

public static Object changePointer(Object param) {
    return new Object();
}

Refer to the below (crudely drawn) diagram:

enter image description here

As you can see, both Object 1 and Object 2 point to the same memory location.

My question: Is it possible to change the pointer of Object 1 using only the variable Object 2?

Other Information to Consider:

  1. I have no access to the creation of or any of the code that is part of Example.
  2. I DO have access to an instance of Example.
  3. I have no access to the creation of original inside of Example.
  4. I have no access to many of the methods that make use of original.
  5. changePointer(Object param) may not be necessary. If it is possible to in some other way gain access to and change original, that would result in the same effect.

NOTE: I understand the concept of pass by reference vs pass by value. I know Java is pass by value, and that's not what I'm asking. I'm asking if there is any way, knowing that Java is pass by value, for the above to be possible.

Jaykishan
  • 1,409
  • 1
  • 15
  • 26
user3144349
  • 419
  • 1
  • 4
  • 12
  • Point to a new type of object or object of the same type? Sounds like you want to cast `Object 1` into `Object 2` – Brendan Lesniak May 20 '14 at 21:54
  • 1
    No. The variable `original` is local to method `exampleMethod` and cannot be referenced from outside that method. – Hot Licks May 20 '14 at 21:55
  • Answer to your NOTE: no. – Haozhun May 20 '14 at 21:55
  • @Brendan I mean that Object 1 and 2 or objects of the same type. The type is irrelevant, but they are the same type. I'll add some clarification to the question. – user3144349 May 20 '14 at 21:56
  • @HotLicks Okay, that's what I was afraid of. It looks like I'm out of luck then. – user3144349 May 20 '14 at 21:59
  • Do you __really__ need to change what instance the variable is referencing? Would it be possible to just return the new instance and have the caller assign the result to the variable? – unholysampler May 20 '14 at 21:59
  • There are at least a half-dozen ways to achieve the same effect. You will learn them as you learn more about Java. No need to further contort your brain just yet, though. – Hot Licks May 20 '14 at 22:00
  • @HotLicks I know plenty about Java. The situation I am in is very unique, and this is the only way to accomplish it in my case. I'll add some more information above to illustrate why. – user3144349 May 20 '14 at 22:04
  • What is `c` in your code? It's confusing. – ajb May 20 '14 at 22:06
  • I've made some fairly drastic changes to the original question. Probably won't change anything, but might open up some other possibilities. – user3144349 May 20 '14 at 22:17
  • You may want to review the edit and just clean it up. There are some sentences that are referring to things you had in your previous version. Also, the answer doesn't change, because of _pass-by-value_. – Sotirios Delimanolis May 20 '14 at 22:31

2 Answers2

4

Since Java is pass-by-value always, what you are asking for is not directly possible.

The usual work around is to use an array of the target type with size one. You pass the array and modify the reference inside it to a new one.

Object actualOriginal = new Object();
Object original[] = new Object[] {actualOriginal};
...
public static void changePointer(Object[] param) {
    param[0] = new Object();
    //Change the pointer of original
}
...
// original[0] now has a reference to whatever you set in changePointer(..)
Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    This way, `actualOriginal` is not modified to point to the new object. – Haozhun May 20 '14 at 21:57
  • @Haozhun Yeah, that's what I'm saying. The workaround is to use the array `original`. – Sotirios Delimanolis May 20 '14 at 21:58
  • This is useful, but the problem is that I can't control how `actualOriginal` is used. Because `actualOriginal` is used by code that I don't have access to, the above solution wouldn't work in my specific case. I think I'm going to have to accept that what I'm asking simply isn't possible due to the nature of Java. – user3144349 May 20 '14 at 22:02
  • @user3144349 You're out of luck it seems :(. – Sotirios Delimanolis May 20 '14 at 22:04
1

You could do it reflectively, but it will be brittle depending on how much the code changes.

public static Example changeOriginalPointer(Example param, Object newOriginal) 
{
    Field originalField=clazz.getDeclaredField("original");

    originalField.setAccessible(true);
    originalField.set(param, newOriginal);
    originalField.setAccessible(false); //this is probably not necessary
}