Подтвердить что ты не робот

Есть ли интерфейс, похожий на Callable, но с аргументами?

Есть ли интерфейс в Java, подобный интерфейсу Callable, который может принимать аргумент в свой метод вызова?

Так же:

public interface MyCallable<V> {
  V call(String s) throws Exception;
}

Я бы предпочел не создавать новый тип, если уже есть что-то, что я могу использовать. Или есть лучшая стратегия для внедрения нескольких клиентов и подключения к вызываемой процедуре?

Скопировано здесь http://www.programmingforums.org/thread27905.html

4b9b3361

Ответ 1

Так как Java 8 существует целый набор функционально-подобных интерфейсов в пакете java.util.function. Тот, который вы просите специально, это просто Function.

До Java 8 для этого не было встроенного интерфейса общего назначения, но некоторые библиотеки предоставили его.

Например Guava имеет интерфейс Function<F,T> с методом T apply(F input). Он также делает интенсивное использование этого интерфейса в нескольких местах.

Ответ 2

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

Я решил это так:


edit: в последнее время я просто использую это:

    public static abstract class callback1<T>{
         public abstract  void run(T value);
    }

    public static abstract class callback2<T,J>{
         public abstract  void run(T value,J value2);
    }

    public static abstract class callback3<T,J,Z>{
         public abstract  void run(T value,J value2,Z value3);
    }


    public static abstract class callbackret1<R,T>{
         public abstract  R run(T value);
    }

    public static abstract class callbackret2<R,T,J>{
         public abstract  R run(T value,J value2);
    }

    public static abstract class callbackret3<R,T,J,Z>{
         public abstract  R run(T value,J value2,Z value3);
    }

CallBack.java

public abstract class CallBack<TRet,TArg> {
    public abstract TRet call(TArg val);
}

определить метод:

class Sample2 
{
    CallBack<Void,String> cb;
    void callcb(CallBack<Void,String> CB)
    {
     cb=CB; //save the callback
     cb.call("yes!"); // call the callback
    }
}

Использовать метод:

sample2.callcb(new CallBack<Void,String>(){
        @Override
        public Void call(String val) {
            // TODO Auto-generated method stub
            return null;
        }
    });

образец двух аргументов: CallBack2.java

public abstract class CallBack2<TRet,TArg1,TArg2> {
    public abstract TRet call(TArg1 val1,TArg2 val2);
}

обратите внимание, что, когда вы используете тип возврата Void, вы должны использовать return null; поэтому здесь есть вариант исправить это, потому что обычно обратные вызовы не возвращают никакого значения.

void как возвращаемый тип: SimpleCallBack.java

public abstract class SimpleCallBack<TArg> {
    public abstract void call(TArg val);
}

void как возвращаемый тип 2 args: SimpleCallBack2.java

public abstract class SimpleCallBack<TArg1,TArg2> {
    public abstract void call(TArg1 val1,TArg2 val2);
}
Интерфейс

не подходит для этого.

Интерфейсы

позволяют нескольким типам соответствовать одному типу. используя общий предопределенный набор функций.

абстрактные классы позволяют пустым функциям внутри них заполняться позже. при расширении или создании экземпляра.

Ответ 3

Недавно у меня было такое же требование. Как объяснили другие, многие библиотеки предоставляют "функциональные" методы, но они не генерируют исключений.

Примером того, как некоторые проекты предоставили решение, является библиотека RxJava, где они используют интерфейсы, такие как ActionX, где "X" - 0... N, количество аргументов метода вызова. У них даже есть интерфейс varargs, ActionN.

Мой текущий подход заключается в использовании простого общего интерфейса:

public interface Invoke<T,V>  {     
    public T call(V data) throws Exception;     
//  public T call(V... data) throws Exception;    
}

Второй способ предпочтительнее в моем случае, но он показывает, что эта опасная "Тип безопасности: потенциальное загрязнение кучи через данные параметров varargs" в моей среде IDE, и это еще одна проблема.

Другим подходом, который я рассматриваю, является использование существующих интерфейсов, таких как java.util.concurrent.Callable, которые не выбрасывают Exception, а в моей реализации исключают исключение из неконтролируемых исключений.

Ответ 4

Ответ неоднозначен. Строго говоря, то есть, "с той же целью интерфейса Callable", нет.

Существуют похожие классы, и в зависимости от того, что вы хотите, они могут быть или не быть удобными. Одним из них является SwingWorker. Однако, как следует из названия, он был разработан для использования в рамках Swing. Он может использоваться для других целей, но это будет плохой выбор дизайна.

Мой лучший совет - использовать тот, который предоставляется библиотекой расширений (Jakarta-Commons, Guava и т.д.), в зависимости от того, какие библиотеки вы уже используете в своей системе.

Ответ 5

Начиная с Java 1.8 существует интерфейс Supplier<T>. У него есть метод get() вместо call() и он не объявляет выброшенное исключение.

Ответ 6

Обычно аргументы не требуются, поскольку метод может иметь любое количество аргументов в своем конструкторе.

final int i = 5;
final String word = "hello";

Future<String> future = service.submit(new Callable<String>() {
    public String call() {
        return word + i;
    }
});

В этом примере использовались i и word, но вы можете "передать" любое количество параметров.

Ответ 7

У меня была такая же проблема. вы можете обернуть любой метод, чтобы вернуть вызываемый, и выполнить его возвращаемое значение. то есть.

 main {    
    Callable<Integer> integerCallable = getIntegerCallable(400);
    Future<Integer> future = executor.submit(integerCallable);
}

private Callable<Integer> getIntegerCallable(int n) {
    return () -> {
            try {
                TimeUnit.SECONDS.sleep(n);
                return 123;
            } catch (InterruptedException e) {
                throw new IllegalStateException("task interrupted", e);
            }
        };
}

Ответ 8

Определите интерфейс следующим образом:

interface MyFunction<I, O> {
    O call(I input);
}

Определите метод:

void getOrderData(final Function<JSONArray, Void> func){
    ...
    JSONArray json = getJSONArray();
    if(func!=null) func.call(json);           
}

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

//call getOrderData somewhere in your code
getOrderData(new Function<JSONArray, Void>() {
        @Override
        public Void call(JSONArray input) {
            parseJSON(input);                
            return null;
        }
});