3

I'm coming from an Objective-C background. In Objective-C, you can store references to methods by using @selector variables, for example @selector(terminate). Then, you can simply "apply" those selectors on objects, which executes the method described by the selector.

Now, I have to program something in Java. Is there anything similar to this in Java? Or a workaround?

EDIT: Basically, I'm creating a CLI program. When I read in the commands, I have to map the commands to certain methods. I thought about creating a dictionary associating a command with a method selector.

ryyst
  • 9,563
  • 18
  • 70
  • 97
  • If possible it would be interesting for you to add a summary of the problem you are solving. There may be a more Java-like way to solve it that you have not considered. – Russ Hayward Jan 27 '11 at 15:07
  • Thanks - I have updated my answer to suggest a design. – Russ Hayward Jan 27 '11 at 17:14
  • possible duplicate of [What's the nearest substitute for a function pointer in Java?](http://stackoverflow.com/questions/122407/whats-the-nearest-substitute-for-a-function-pointer-in-java) – nawfal Jul 05 '14 at 07:49

2 Answers2

4

Nothing nice. The only method to enable you to do a similar thing is reflection:

public class ReflectionExample {
    private static class A {
        public void foo() {
            System.out.println("fooing A now");
        }
    }

    public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException,
            IllegalAccessException, InvocationTargetException {
        Method method = A.class.getMethod("foo");
        method.invoke(new A());
    }
}

And then you can only call Method.invoke on an object of the same class (or a subclass).

EDIT: To solve your exact problem I think you are probably best creating one class for each command. Each of these classes can implement an interface that will contain the method to perform the command and probably also a String getter for the name of the command. You can then populate a collection with command instances.

The only danger of this method is you add a new command class and forget to create an instance of it. The best method I have found to avoid that is to use an enumeration with one member for each command. To create the instances you can iterate over the enumerations values and use a switch case to create the instances. Some IDEs (such as Eclipse) can generate a warning or error if an enumeration instance is not covered in a switch - that will tell you immediately if you have forgotten to create a command instance.

Russ Hayward
  • 5,617
  • 2
  • 25
  • 30
  • 1
    Just be aware, that the performance of reflection calls is awful. – Jules Jan 27 '11 at 11:04
  • Good point. Plus it kills type safety and is a security issue (hence the SecurityException). – Russ Hayward Jan 27 '11 at 11:08
  • 2
    yes, but not awful enough to warrant it's use where it can add value. It used to be poor, but is much faster on modern Java VM's. Besides, most ORM's make very heavy use of reflection, so it can't be that slow. – Michael Wiles Jan 27 '11 at 12:51
3

Anonymous inner class like here

Community
  • 1
  • 1
ayush
  • 14,350
  • 11
  • 53
  • 100
  • 1
    Hm, I was hoping to be able to store the method name in a String, or something like that. Using anonymous inner classes doesn't look fun. – ryyst Jan 27 '11 at 10:58
  • it surely is not fun. but that's the closest thing possible. – ayush Jan 27 '11 at 11:01
  • 1
    anything but if-else blocks... inner classes ftw. For each different method option you want, create an inner class and then pass in the relevant instance of the inner class. – Michael Wiles Jan 27 '11 at 12:52
  • +1 @Michael. I agree - avoid complex if else structures at all costs! – Russ Hayward Jan 27 '11 at 15:09
  • if you desperately want to use strings, one way is to create a bunch of inner classes, one for each option in terms of the method you want to call and then create a map that maps the "method name" as a string against the relevant inner class instance that calls that method name. – Michael Wiles Jan 28 '11 at 12:39
  • This is more like block in iOS, more than @selector. – CopperCash Jun 26 '14 at 02:26