Эквивалент анонимных методов C # в Java?

В C # вы можете определять делегатов анонимно (даже если они не более чем синтаксический сахар). Например, я могу это сделать:

public string DoSomething(Func<string, string> someDelegate)
{
     // Do something involving someDelegate(string s)
} 

DoSomething(delegate(string s){ return s += "asd"; });
DoSomething(delegate(string s){ return s.Reverse(); });

Можно ли передать такой код на Java? Я использую среду обработки, которая имеет довольно старую версию Java (у нее нет универсальных шаблонов).


person Callum Rogers    schedule 27.08.2009    source источник
comment
Вопрос о делегатах в Java в целом   -  person nawfal    schedule 04.07.2014


Ответы (6)


До Java 8:

Ближайшие к делегатам Java - интерфейсы с одним методом. Вы можете использовать анонимный внутренний класс.

interface StringFunc {
   String func(String s);
}

void doSomething(StringFunc funk) {
   System.out.println(funk.func("whatever"));
}

doSomething(new StringFunc() {
      public String func(String s) {
           return s + "asd";
      }
   });


doSomething(new StringFunc() {
      public String func(String s) {
           return new StringBuffer(s).reverse().toString();
      }
   });

Java 8 и выше:

Java 8 добавляет в язык лямбда-выражения.

    doSomething((t) -> t + "asd");
    doSomething((t) -> new StringBuilder(t).reverse().toString());
person Michael Lloyd Lee mlk    schedule 27.08.2009
comment
[Коллекции Google] [1] и Groovy [2] могут вас заинтересовать. [1] code.google.com/p/google-collections [2] groovy.codehaus.org - person Michael Lloyd Lee mlk; 27.08.2009

Не совсем так, но в Java есть нечто подобное.

Это называется анонимными внутренними классами.

Позвольте мне привести Вам пример:

DoSomething(new Runnable() {
   public void run() {
       // "delegate" body
   }
});

Это немного более подробно и требует интерфейса для реализации, но в остальном это почти то же самое.

person Gregory Mostizky    schedule 27.08.2009

Ваш пример на Java будет выглядеть так, используя аномальные внутренние классы:

interface Func {
    String execute(String s);
}

public String doSomething(Func someDelegate) {
    // Do something involving someDelegate.execute(String s)
}

doSomething(new Func() { public String execute(String s) { return s + "asd"; } });
doSomething(new Func() { public String execute(String s) { return new StringBuilder(s).reverse().toString(); } } });
person Jesper    schedule 27.08.2009

Можно ли передать такой код на Java? Я использую среду обработки, которая имеет довольно старую версию Java (у нее нет универсальных шаблонов).

Поскольку заданный вопрос об ответе, относящемся к обработке, не имеет прямого эквивалента. Но Processing использует уровень языка Java 1.4, а Java 1.1 представила анонимные внутренние классы, которые являются грубым приближением.

person John Feminella    schedule 27.08.2009

Например :

public class Delegate
{
    interface Func
    {
        void execute(String s);
    }

    public static void doSomething(Func someDelegate) {
        someDelegate.execute("123");
    }

    public static void main(String [] args)
    {

        Func someFuncImplementation = new Func() 
        {
            @Override
            public void execute(String s) {
                System.out.println("Bla Bla :"  + s);
            }
        };

        Func someOtherFuncImplementation = new Func() 
        {
            @Override
            public void execute(String s) {
                System.out.println("Foo Bar:"  + s);
            }
        };


        doSomething(someFuncImplementation);
        doSomething(someOtherFuncImplementation);
    }
}

Вывод :

Бла Бла: 123

Бар Foo: 123

person JAN    schedule 11.09.2015

Здесь вы все забыли, что делегат C # в первую очередь - это потокобезопасный. Эти примеры предназначены только для однопоточного приложения.

Большинство современных приложений написаны на основе многопоточной концепции. Так что однозначного ответа нет.

В Java нет эквивалента

person Community    schedule 10.08.2017
comment
Дело не в том, что вы говорите неправильно. Это правильно. Проблема в том, что это на самом деле не отвечает на заданный вопрос, а просто говорит, что все остальные ответы неверны. Вы хотите сказать, что в Java не существует не эквивалента? - person Cody Gray; 13.08.2017
comment
Для большинства пользователей разница здесь невелика. Я бы даже сказал, что отсутствие многоадресной рассылки - большая разница между ними. Что касается формулировки вопроса, я считаю, что приведенные выше ответы верны. Всем ясно, что речь идет о самом близком к Java. - person Michael Lloyd Lee mlk; 25.04.2018
comment
Поскольку ссылки являются атомарными, версия Java не выйдет из строя, но у вас могут быть устаревшие данные. Чтобы сделать его потокобезопасным, все, что вам нужно сделать, это добавить ключевое слово volatile. - person Michael Lloyd Lee mlk; 25.04.2018