views:

178

answers:

5

This is something like Reflection where you can call a method simply by its name, and not a precompiled pointer to it.

Like in JavaScript you can:

var fun = function(){    alert("Hello World!");    }
fun();

Is something like that possible in Java/J2ME? How?

+1  A: 

Are you after the dynamic creation of methods or Reflection?

The first you can't do in Java but you could use an interpreter (BeanShell if you want Java).

mlk
+2  A: 

If you want an interpreter for j2me, you could check out Hecl: http://www.hecl.org

You definitely can't do most of the 'fancy' things you can do in normal Java in J2ME. The alternative is a series of if/elseif's that then call the function you want, but you still have to know that ahead of time so that you can write the code that does that.

David N. Welton
+2  A: 

One way to imitate this functionality is to create a strategy class.

interface Function
{
    Object call(Object[] arguments);
}

To do what you suggested, simply do the following (a bit more verbose, as Java typically is):

static class Fun implements Function
{
    public Object call(Object[] arguments)
    {
        System.out.println("Hello, world");
        return null;
    }
}

Function fun = new Fun();
fun.call(null);

Depending on the situation, you might be able to use better types or generics instead of Object and Object[] (in this case, I used them for maximum flexibility, but they don't give you much in the way of type checking so it's not ideal).

For more information, look at the strategy design pattern.

Imagist
+1  A: 

There are at least a few ways:

You could create classes at runtime with BCEL, but you have to create the bytecodes yourself. And the JVM's verifier might reject your class if your bytecodes look iffy. Not a super easy solution but doable.

Sun's Java 6 implementation includes Rhino, the JavaScript interpreter, so you can perhaps do what you need if you're willing to use a little JavaScript.

I'm not too sure about this but I believe if you have the JDK installed, you can invoke javac from your Java program. javac's output could be loaded at runtime with a custom ClassLoader class.

mcjabberz
+2  A: 

The common way of getting something like Javascript's closures is using anonymous inner classes. It's a lot more verbose, but it lets you do pretty much the same thing.

Runnable r = new Runnable(){
    public void run(){
        System.out.println("Hello, world!");
    }
};
r.run(); // Prints "Hello, world!"

You can even reference variables in the enclosing method, if they're final:

public static Runnable makeGreeter(final String who) {
    return new Runnable() {
        public void run() { 
            System.out.println("Hello, " + who + "!"); 
        }
    };
}

// ... elsewhere in your program...
Runnable r = makeGreeter("world");
r.run(); // "Hello, world!"

This is standard stuff which has been in Java since the beginning. Runnable is a very handy interface which, according to the Javadocs, "should be implemented by any class whose instances are intended to be executed by a thread". Runnable can be used for a lot more than threads, of course, and is generally used (in the JVM and elsewhere) as "something that can be executed" - pretty much like a function in Javascript. Of course, if you want to pass arguments, you'd have to make your own interface, but those can be implemented anonymously as well. For example, using @Imagist's Function interface:

interface Function {
    Object call(Object[] arguments);
}

// ...
Function helloSayer = new Function(){
    public Object call(Object[] args){
        System.out.println("Hello, " + args[0] + "!");
    }
};
helloSayer.call(new Object[]{ "world" }); // "Hello, world!"

Edit: This has nothing to do with reflection, of course, but there's no reflection in your example either - just an anonymous function.

gustafc