Как объявить функцию во время выполнения программы?
-
05-07-2019 - |
Вопрос
Это что-то вроде Reflection , где вы можете вызвать метод просто по его имени, а не по предварительно скомпилированному указателю на него.
Как и в JavaScript, вы можете:
var fun = function(){ alert("Hello World!"); }
fun();
Возможно ли что-то подобное в Java / J2ME? Как?
Решение
Если вам нужен переводчик для j2me, вы можете проверить Hecl: http://www.hecl.org а> р>
Вы определенно не можете делать большинство «причудливых» вещей, которые вы можете делать в обычной Java в J2ME. Альтернативой является серия if / elseif, которые затем вызывают нужную вам функцию, но вы все равно должны знать об этом заранее, чтобы вы могли написать код, который делает это.
Другие советы
Один из способов имитировать эту функциональность - создать класс стратегии.
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 []
(в данном случае я использовал их для максимальной гибкости , но они не дают вам много способов проверки типов, так что это не идеально).
Дополнительную информацию смотрите в шаблоне разработки стратегии .
Обычный способ получить что-то вроде замыканий в 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 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: Конечно, это не имеет ничего общего с отражением, но в вашем примере это тоже не отражение - просто анонимная функция.
Вы после динамического создания методов или Reflection ? Р>
Первое, что вы не можете сделать в Java, но можете использовать переводчика ( BeanShell , если хотите) Java).
Есть как минимум несколько способов:
Вы можете создавать классы во время выполнения с помощью BCEL , но вы должны сами создавать байт-коды. И верификатор JVM может отклонить ваш класс, если ваши байт-коды выглядят ненадежно. Не супер простое решение, но выполнимое. Р>
Реализация Sun 6 в Java включает в себя Rhino , интерпретатор JavaScript, так что вы, возможно, сможете делать то, что вам нужно если вы готовы использовать немного JavaScript. Р>
Я не слишком уверен в этом, но я полагаю, что если у вас установлен JDK, вы можете вызвать javac
из вашей Java-программы. Вывод javac
может быть загружен во время выполнения с помощью пользовательского класса ClassLoader
.