Как объявить функцию во время выполнения программы? - PullRequest
2 голосов
/ 11 сентября 2009

Это что-то вроде Reflection , где вы можете вызывать метод просто по его имени, а не скомпилированным указателем на него.

Как и в JavaScript, вы можете:

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

Возможно ли что-то подобное в Java / J2ME?Как?

Ответы [ 5 ]

2 голосов
/ 12 сентября 2009

Обычный способ получить что-то вроде замыканий в 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!"

Редактировать: Конечно, это не имеет ничего общего с отражением, но в вашем примере также нет отражения - только анонимная функция.

2 голосов
/ 11 сентября 2009

Если вам нужен переводчик для j2me, вы можете проверить Hecl: http://www.hecl.org

Вы определенно не можете делать большинство «причудливых» вещей, которые вы можете делать в обычной Java в J2ME. Альтернативой является серия if / elseif, которые затем вызывают нужную функцию, но вы все равно должны знать об этом заранее, чтобы вы могли написать код, который это делает.

2 голосов
/ 11 сентября 2009

Один из способов имитировать эту функциональность - создать класс стратегии.

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);

В зависимости от ситуации, вы можете использовать более совершенные типы или непатентованные символы вместо Object и Object[] (в данном случае я использовал их для максимальной гибкости, но они не дают вам большого эффекта проверки типа, так что это не идеально).

Для получения дополнительной информации посмотрите шаблон проектирования стратегии .

1 голос
/ 11 сентября 2009

Есть как минимум несколько способов:

Вы можете создавать классы во время выполнения с BCEL , но вы должны сами создавать байт-коды. И верификатор JVM может отклонить ваш класс, если ваши байт-коды выглядят ненадежно. Не супер простое решение, но выполнимое.

Реализация Sun 6 в Sun включает в себя Rhino , интерпретатор JavaScript, так что вы можете, возможно, делать то, что вам нужно, если вы хотите использовать немного JavaScript.

Я не слишком уверен в этом, но я верю, что если у вас установлен JDK, вы можете вызвать javac из вашей Java-программы. Вывод javac может быть загружен во время выполнения с помощью пользовательского класса ClassLoader.

1 голос
/ 11 сентября 2009

Вы после динамического создания методов или Reflection ?

Первое, что вы не можете сделать в Java, но вы можете использовать интерпретатор ( BeanShell , если вы хотите Java).

...