如何在程序执行期间声明一个函数?

时间:2009-09-11 15:09:32

标签: java reflection function java-me hecl

这类似于Reflection,您只需按名称调用方法,而不是预编译指针。

与JavaScript一样,您可以:

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

在Java / J2ME中是否可以这样?怎么样?

5 个答案:

答案 0 :(得分:2)

如果您想要j2me的翻译,可以查看Hecl:http://www.hecl.org

你绝对不能做你在J2ME中用普通Java做的大部分“花哨”的事情。替代方案是一系列if / elseif然后调用你想要的函数,但你仍然需要提前知道,以便你可以编写那样做的代码。

答案 1 :(得分:2)

模仿此功能的一种方法是创建策略类。

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

要做你的建议,只需执行以下操作(比Java通常更详细):

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

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

根据具体情况,您可以使用更好的类型或泛型,而不是ObjectObject[](在这种情况下,我使用它们以获得最大的灵活性,但它们不会给您很多类型检查的方式,所以它并不理想。)

有关详细信息,请查看strategy design pattern

答案 2 :(得分:2)

获得类似Javascript的闭包的常用方法是使用匿名内部类。它更冗长,但它可以让你做同样的事情。

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

如果它们是最终的,您甚至可以在封闭方法中引用变量:

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!"

这是标准的东西,从一开始就在Java中。 Runnable是一个非常方便的接口,根据Javadocs,“应该由任何其实例都由一个线程执行的类实现”。当然,Runnable可以用于线程以外的任务,并且通常用于(在JVM和其他地方)作为“可以执行的东西” - 非常类似于Javascript中的函数。当然,如果你想传递参数,你必须创建自己的界面,但这些也可以匿名实现。例如,使用@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!"

编辑:当然,这与反射无关,但你的例子中没有任何反映 - 只是一个匿名函数。

答案 3 :(得分:1)

您是在动态创建方法还是Reflection之后?

你不能用Java做的第一个,但如果你想要Java,你可以使用解释器(BeanShell。)

答案 4 :(得分:1)

至少有几种方法:

您可以使用BCEL在运行时创建类,但您必须自己创建字节码。如果您的字节码看起来不合适,JVM的验证程序可能会拒绝您的类。不是一个超级简单的解决方案,但可行。

Sun的Java 6实现包括Rhino,JavaScript解释器,所以如果你愿意使用一点JavaScript,你也许可以做你需要的。

我对此不太确定,但我相信如果你安装了JDK,你可以从Java程序中调用javacjavac的输出可以在运行时使用自定义ClassLoader类加载。