Calling a delegate method in Java

In Java: What is the best way to pass a method from one object to another so that it can be called later by a second object?

I'm coming from an ActionScript background where it is as easy to pass method references as it is to pass variable references, but it's much more complicated in Java. The first few links I found say this is not possible (and it may have been at the time they were posted), but then I found http://www.javacamp.org/javavscsharp/delegate.html which is detailed, How can I do that.

My problem using the Javacamp example is a string based method reference. Methods get renamed all the time and the string reference will only complain after you actually run that function runtime, not compile time for the correct explicit reference.

Isn't there a way to do this with the correct explicit references to the method you want another class to execute?

Model of what I hope to accomplish:

  • The player clicks the refresh button on Activity1> Activity1 passes the refresh method to a new confirmation operation.
  • Player clicks "Yes"> Activity Acknowledgment calls the update method passed from Activity1
  • OR: Player clicks No> Confirmation action closes

EDIT: To be clear, I'm not looking for a static method solution, as my Confirmation operation requires that I have many lines of logic for which the static method is to be called. The keep alive will be used throughout my application: a simple "Are you sure you want X?" -Yes-No, if yes, do X

I am currently looking at implementing onActivityResult to avoid this issue, but that would be more logic than I like in this question.

+3


source to share


4 answers


you can use interfaces like this:

public interface MyMethod {
    public void method();
}


public class FirtObject{

    private SecondObject ob;

    public void tellSecondObjectExecuteLater(){
        ob.executeLater( new MyMethod() { 
          public void method(){System.out.println("duh Method");} });
    }
}

public class SecondObject {

    private MyMethod myMth;

    public void executeLater(MyMethod mth){
        myMth = mth;
    }

    public void executeNow(){
        myMth.method();
    }
}

      



does this solve your problem?

+6


source


The typical way to pass methods is to use an interface and anonymous inner classes. To support static typing, an interface is used to declare the method signature and enter information. The caller can use a concrete implementation of this interface like a regular class, or use Anonymous Inner Classes to quickly create a class. I'll use the standard Java SDK classes for illustration:

interface Comparator<T> {
    public int compare( T a, T b); 
}

class SpecialCollection<T> {
    public void sort( Comparator<T> comparator ) {...} 
}

public class SomeClient {
    public void doSomething( SpecialCollection<SpecialObj> collection ) {

        collection.sort( new Comparator<SpecialObj>() {
           public int compare( SpecialObject a, SpecialObject b ) {
               // some implementation
           }
        } );
    }
}

      



The above is an example of a strategy pattern. As for the strategy pattern (and passing callback methods like in Javascript). The author must plan for these types of extensions. The author has to predict ahead of where he wants you to expand. And it's just very clean if you are using interfaces.

However, pure delegation does not have to include interfaces. You can pass specific classes as Java can always pass a subclass that overrides various methods of that class to change the way you call or code. For example, in Java, InputStream / OutputStream are abstract classes and you usually pass instances of the subclass to methods.

+1


source


If you want a way to act differently depending on the context (AKA, it differs depending on how it is instantiated), you need to walk through the instance of the class that the method is in.

If it is a static method, you can simply refer to the method itself if you import that class at the beginning of a new class.

For example, let's say you have a method that will tell you about some string. IF the class looks like this:

class stringChecker {
    private String stringToCheck;
    public class stringChecker(String s) {
         stringToCheck = s;
    }
    public int getStringLength() {
         return stringToCheck.length();
    }
    public boolean stringStartsWith(String startsWith) {
         return (stringToCheck.indexOf(startsWith) == 0);
    }
}

      

Then you will want to iterate over the instance since it is non-static. Different instances have different strings they were created with, so you get a different return if you use a different instance.

However, if your class looks more like this:

class stringChecker {
     public static int getStringLength(String s) {
          return s.length();
     }
     public static boolean stringStartsWith(String s, String startsWith) {
          return (s.indexOf(startsWith) == 0);
     }
}

      

Then you can simply refer to these methods with stringChecker.getStringLength ("test"); because the methods are static. It doesn't matter which instance they are in. The result returned depends ONLY on what is being passed. You just need to make sure to add import stringChecker; at the top or whatever your class gets called. For you, it will probably be something like com.example.blah.otherthing.stringChecker since you are working with Android.

Good luck! Hope this helps :)

EDIT: Looks like I may have read the issue too quickly ... if this is not what you asked for, just let me know with a comment and I will delete this answer so that no one is confused.

0


source


You said you were using it in a project to open a commit operation.

Actions should not contain references to each other to avoid memory leaks. Use the Intent class to pass data between activities. To get the result, call the StartActivityForResult () function and get the result in the onActivityResult () method.

But in general, AlertDialog or PopupWindow is more suitable for your task.

0


source







All Articles