Самовыполняющиеся методы Java

В JavaScript можно написать такую ​​самовыполняющуюся функцию:

(function foo() {
    console.log("bar");
}());

Я хочу сделать это на Java. Так, например:

// This code does not work obviously
public static void main(String[] args) {
    (foo() {
        System.out.println("bar");
    }());
}

Что-то подобное существует?


person rink.attendant.6    schedule 18.06.2014    source источник
comment
Зачем вам здесь нужна функция? Какова ваша цель? Знаете ли вы, что область видимости работает по-разному в Java и JavaScript?   -  person Denys Séguret    schedule 18.06.2014
comment
Если вас это устраивает, то можно завернуть код в свои блоки { }. Итак, foo: { System.out.println("bar"); } работает.   -  person Unihedron    schedule 18.06.2014


Ответы (3)


Этот javascript на самом деле не создает «самоисполняющуюся» функцию. Это определение функции, а затем ее немедленное выполнение.

Java не позволяет вам определять автономные функции, поэтому вы не можете сделать это в Java. Однако вы можете объявить анонимный класс и немедленно выполнить один из его методов:

new Runnable() {
  @Override
  public void run() {
    System.out.println("hello");
  }
}.run();

Иногда это делается с новыми потоками. Что-то типа:

new Thread(new Runnable() {
    // override Runnable.run
}).start();

(Хотя во многих случаях вы захотите улучшить управление потоками — например, отправить исполняемый файл в службу-исполнитель.)

person yshavit    schedule 18.06.2014
comment
Это не анонимная функция, она называется foo. - person rink.attendant.6; 18.06.2014
comment
@ rink.attendant.6 Хороший вопрос, я отредактирую. Может ли foo быть вызвана позже (т. е. вне его собственной области видимости)? - person yshavit; 18.06.2014
comment
Нет, имя просто для облегчения отладки. - person rink.attendant.6; 18.06.2014
comment
Имя часто используется и в рекурсии. - person Denys Séguret; 18.06.2014

Как уже говорили другие, нет особых причин делать это на Java, поскольку причины для этого в JavaScript не являются проблемами в Java. Но вы можете сделать это в Java 8:

((Runnable)(() -> System.out.println("Hello, world"))).run();

что, по сути, то же самое, что и ответ @yshavit в Java 7.

person ajb    schedule 18.06.2014
comment
вот причина: private static final JAXBContext ctx = ((Supplier<JAXBContext>)(() -> { try { return JAXBContext.newInstance(""); } catch (JAXBException e) { throw new RuntimeException(e); } })).get(); - person djeikyb; 17.12.2014
comment
@djeikyb Хороший пример, но ... Похоже, для этого должен быть более чистый механизм, чтобы вы могли написать что-то вроде private static final JAXBContext ctx = convertExceptionsToRuntimeException(() -> JAXBContext.newInstance(""));. Я думаю, что такой метод можно было бы написать. - person ajb; 17.12.2014
comment
Ага. Вам нужен интерфейс UnsafeSupplier, который разрешает Exception, а затем метод, чтобы обернуть его в Supplier. И тогда вам это нужно для всех функциональных интерфейсов, которые вы используете. И тогда, может быть, иногда вы хотите войти и бросить вместо того, чтобы бросать. Таким образом, метод обертывания может занять Consumer<Exception>... - person djeikyb; 17.12.2014
comment
@djeikyb Я только что попытался написать метод, о котором говорил, и столкнулся с некоторыми неприятными сбоями в обработке исключений с лямбда-выражениями, о которых я не знал. Какой беспорядок. - person ajb; 17.12.2014
comment
Ха. Да, я работал в коде на английском языке, который я написал. Проверенные исключения действительно начинают отстой, когда вы начинаете работать с функциональными интерфейсами из стандартной библиотеки. Я, возможно, подброшу это позже, если кому-то будет интересно. - person djeikyb; 17.12.2014
comment
@ajb, поскольку причины для этого в JavaScript не являются проблемами в Java - относится ли это к проблемам с пространством имен? - person Abdul; 10.08.2016
comment
@Abdul Извините, вы спрашиваете меня о том, что я сказал более 2 лет назад. Я не помню, что имел в виду, и в то время я мало использовал Javascript. - person ajb; 11.08.2016

Вы можете создать вспомогательные методы (например, run и get), которые будут выполнять вашу пользовательскую функцию.

используйте run, если функция ничего не возвращает (побочные эффекты), и get в противном случае

import java.util.function.Supplier;

public interface MyApp {

    static void run(Runnable supp) {
        supp.run();
    }

    static <R> R get(Supplier<R> supp) {
        return supp.get();
    }

    static void test() {

        run(() -> System.out.println("bar"));
        var v = get(() -> "Hello");

    }

}
person Alexander Kondaurov    schedule 11.08.2020