javareflection

Java: Check if a given method name exist in compile time


I'm developing a utility class to handle Actions from Java Swing components; I would like to know if there is a way of checking if a given method name (that will be accessed by reflections) exists in compile time, and show a compiler error if not?

--update

Ok, looks like I was not clear, lets talk about the details:

I have a class called TomAction that I use to simplify simple actions declarations in my project. Instead of write something like:

class MyClass {

    public MyClass() {
    Icon icon = null; // putting null to simplify the example
    JButton btn = new JButton(new AbstractAction("Click to go!", icon) {
        public void actionPerformed(ActionEvent ev) {
        try {
            go();
        } catch (Exception e) {
            e.printStackTrace();
            String msg = "Fail to execute 'go' task.";
            JOptionPane.showMessageDialog(null, msg, "Fail", JOptionPane.ERROR_MESSAGE);
        }
        }
    });
    }

    private void go() {
    // do task
    }

}

..I just write:

class MyClass {

    public MyClass() {
    String msg = "Fail to execute 'go' task.";
    Icon icon = null; // putting null to simplify the example
    TomAction act = new TomAction("go", this, "Click to go!", msg, icon);
    JButton btn = new JButton(act);
    }

    private void go() {
    // do task
    }

}

..and the program have the same behaviour.

The problem is that if I type a wrong method name as argument to TomAction, I will see it just in runtime. I would like to see it in compile time. Got it? :)

By the way, this class is working very fine, I just want to do this enhancement.

--update

studing the Annotations approach


Solution

  • You could use annotation instead of string literal to denote the invoked action and then use APT to verify that the method exists. APT is invoked automatically by the javac.

    http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html#processing http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/overview-summary.html

    By taking your example, I would suggest design as follows - you put a binding annotation in code and add the action instantiation code in the annotation processor. The actions in that case need to be class members which is a good practice anyway. Make sure you use resource bundles for icons and text and you'll save a lot of grief in the long run:

    class MyClass {
        // the keys should be looked up from resource bundle
        @TomActionBinding("go", "text-key", "msg-key", "icon-key");
        Action act;
    
        public MyClass() {
           JButton btn = new JButton(act);
        }
    
        private void go() {
           // do task
        }
    
    }