Xandor
Xandor

Reputation: 450

Edit an object's methods after they've been created in Java

In JavaScript one can create and edit an object's functions on the fly. Is this possible with a Java object's methods? I am essentially wanting something like this:

public class MyObject{
  private int x;
  public MyObject(){x = 0;}
  public myMethod(){}
}

MyObject foo = new MyObject();

and later call something along the lines of:

foo.myMethod = new method({x = 42;});

Upvotes: 0

Views: 122

Answers (5)

Pr0gr4mm3r
Pr0gr4mm3r

Reputation: 6230

In Java you cannot do this like you would do it in Javascript.

But in Java you can achieve such an behavior using the Strategy pattern. For example,

public interface Strategy {
 void doSomething(MyObject obj);
}

public class BasicStrategy implements Strategy {
 public void doSomething(MyObject obj) {
  //do something
 }
}

public class AnotherStrategy implements Strategy {
 public void doSomething(MyObject obj) {
  obj.setX(42);
 }
}

public class MyObject {
  private Strategy actualStrategy = new BasicStrategy();
  private int x = 0;

  public void executeStrategy() {
   actualStrategy.doSomething(this);
  }

  public void setStrategy(Strategy newStrategy) {
    actualStrategy = newStrategy;      
  }

  public void setX(int x) {
   this.x = x;
  }
}

You can alter the behavior of the method at runtime using the following code.

MyObject obj = new MyObject();
obj.setStrategy(new AnotherStrategy());
obj.executeStrategy();

Upvotes: 1

Ashwani
Ashwani

Reputation: 3481

You cannot do this. In java new method is made to return the instance of class Object, not methods. And one thing is to understand is Javascript is an functional programming language and Java is a object oriented language. You cannot treat a method as object in java, also it breaks the security of java encapsulation.

Upvotes: 0

Yes, it's theoretically possible, but you don't want to do it. This sort of thing is black magic, and if you need to ask the question, you're several years from being ready to work with it.

That said, what you're trying to accomplish may be workable with the Strategy design pattern. The idea here is that you define an interface that has the method(s) you need to swap out (say, calculate()), and the class whose behavior you want to change has a field of that interface. You can then modify the contents of that field.

public interface Calculator {
    double calculate(double x, double y);
}

public class MathStuff {
    private Calculator calc;
    ...
    public void doStuff() {
         ...
         result = calc.calculate(x, y);
         ...
    }
}

public class Add implements Calculator {
    public double calculate(double x, double y) {
        return x + y;
    }
}

Upvotes: 0

arshajii
arshajii

Reputation: 129497

It's not directly possible, but you could try something like this:

public class MyObject {
    private int x;

    interface MyMethod {
        void call();
    }

    public MyObject() {
        x = 0;
    }

    public MyMethod myMethod = new MyMethod() {
        @Override
        public void call() {
            x = 42;
        }
    };
}

Upvotes: 2

Josh M
Josh M

Reputation: 11939

You can't edit it in the way that you are trying to demonstrate above, the closest thing you could do to emulate it would be to intercept the method. The only way I could think of at the current moment is to use a MethodInterceptor found within the cglib library to intercept the method.

Upvotes: 1

Related Questions