The Source for Java Technology Collaboration
User: Password:



Evan Summers

Evan Summers's Blog

Explicit Reflection

Posted by evanx on May 04, 2006 at 04:33 AM | Comments (2)

posse5.jpg Like all CodeBoys on the Java frontier, I listen to the JavaPosse.com religiously. It's a great show innit!

So I wrote in to JavaPosse's "If I was king of Java" suggestion-box (episode 49) that I would introduce "explicit reflection" which might be used as below.

public class MyPanel extends JPanel {
   JButton myButton = new JButton();
   public void myButtonActionPerformed(ActionEvent event) {
   }
   protected void configure() {
     configure(myButton, MyPanelInfo.myButton.getName());
     addActionHandler(myButton, MyPanelInfo.myButtonActionPerformed);
   }
}

Where MyPanelInfo magically reflects MyPanel explicitly, as if manually coded as follows.

public final class MyPanelInfo {
  public static final Field myButton = getField(...);
  public static final Method myButtonActionPerformed = getMethod(...);
}

In the example above, the instance name "myButton" might be used to load externalised configuration and preferences for that component, eg. translated text, tool tip, icon, et cetera, for myButton. And the method could be specified to a proxy action listener.

The "explicit reflection" would promote tooling/refactability by avoiding strings as in getMethod("myButtonActionPerformed") and configure(myButton, "myButton").

Rename.png Using strings to refer to instances and methods is "fragile" eg. not "refactoring-safe" (or "exception-safe") and is not readily "toolable" in the sense that it does not enjoy auto-completion and error-highlighting in IDE's.

An alternative to the above that would still work, is to introduce a language notation such as MyPanel:myButton, which to the compiler is just the string literal "myButton", but is understood by the IDE to be the name of the myButton instance, for the purposes of refactoring eg. renaming myButton to something else.

I will follow this up with a blog about tooling and refactoring, in support of the notion that having awesome tools like Netbeans and Eclipse, is what makes Java better suited to many project archetypes compared to alternatives such as Python, C#/Mono and C++/Qt.

Preferences.png But having refactoring capabilities doesn't help if our code is not safely refactorable. And if we use strings to refer fields and methods, then those fields and methods are not safely refactorable. And if our code is not refactorable, then we can't be agile.

In a future blog, i will extend this argument to Java persistence (as in Hibernate, JDO, EJB3), and make an argument for "native queries," which might enable refactoring.

Update. See my follow-on blog "Bean Curd 1."


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • You might want to have a look at my blog entry on this topic.

    I propose a way to extract a method name refactor-safely at runtime. The idea is to create a mock instance of the class in question which with CGLib, invoke the method whose name shall be recorded and record the method name in the mock for later access.

    With a little reflection woodoo you can do


    class TestStub {
    void dummy() {
    }
    }
    ...
    TestStub testStub = ...insert woodoo here...

    testStub.dummy();
    assertEquals("Method recorded", "dummy", methodReference.get().getName());

    Posted by: llucifer on May 04, 2006 at 06:22 AM

  • From my admittedly weak knowledge of C#, this seems awfully like what it calls "delegates", which seemed like a neater alternative to anonymous classes in many cases, although I'm not sure how strongly-typed they are.

    Posted by: skaffman on May 05, 2006 at 12:07 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds