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

Java: параметризованный Runnable

Стандартный Runnable интерфейс имеет только непараметризованный метод run(). Существует также интерфейс Callable<V> с методом call(), возвращающий результат родового типа. Мне нужно передать общий параметр, что-то вроде этого:

interface MyRunnable<E> {
  public abstract void run(E reference);
}
Есть ли какой-либо стандартный интерфейс для этой цели, или я должен объявить этот основной самостоятельно?
4b9b3361

Ответ 1

Как правило, вы должны реализовать Runnable или Callable как класс, поддерживающий порождающий входной параметр; например.

public class MyRunnable<T> implements Runnable {
  private final T t;

  public MyRunnable(T t) {
    this.t = t;
  }

  public void run() {
    // Reference t.
  }
}

Ответ 2

Существует также com.google.common.base.Function<F, T> из Коллекции Google Guava.

Если вы устанавливаете тип вывода на ? или Void (и всегда возвращаете его null), вы можете использовать его в качестве альтернативы Runnable с входным параметром.

Это имеет то преимущество, что можно использовать Functions.compose для преобразования входного значения, Iterables.transform, чтобы применить его к каждому элементу коллекции и т.д.

Ответ 3

Java 8 включает в себя java.util.function.Consumer<T> интерфейс с единственным методом не по умолчанию void accept(T t).

В этом пакете есть много других связанных с ним интерфейсов .

Ответ 4

Обычно, если вы хотите передать параметр в метод run(), вы подклассифицируете Runnable с помощью конструктора, который принимает параметр.

Например, вы хотите сделать это:

// code
Runnable r = new YourRunnable();
r.run(someParam);
//more code

Вам нужно сделать это:

// code
Runnable r = new YourRunnable(someParam);
r.run();
//more code

Вы реализуете YourRunnable, как показано ниже:

public class YourRunnable implements Runnable {
    Some param;
    public YourRunnable(Some param){
        this.param = param;
    }
    public void run(){
        // do something with param
    }
}

Ответ 5

Я предлагаю определить интерфейс, как это сделано в исходном вопросе. Кроме того, избегайте слабой типизации, создавая интерфейс, специфичный для того, что он должен делать, а не бессодержательный интерфейс, например Runnable.

Ответ 6

Runnable не должен вызываться непосредственно клиентским кодом, например foo.run(), который будет запускаться последовательно в текущем потоке.

Из Runnable API:

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

Этот интерфейс предназначен для обеспечения общий протокол для объектов, которые хотите выполнить код, пока они активный. Например, Runnable реализованный классом Thread. бытие активный просто означает, что поток имеет был запущен и еще не был остановился.

Кроме того, Runnable предоставляет означает, что класс должен быть активным не подклассы Thread. Класс, который реализует Runnable, может работать без subclassing Thread, создавая экземпляр Образец темы и передача в как цель. В большинстве случаев Управляемый интерфейс следует использовать, если вы планируете переопределить run() и никакой другой Thread методы. Это важно, потому что классы не должны быть подклассами если программист не намеревается изменения или усиления фундаментальных поведение класса.

Вместо этого вы создаете новый экземпляр Thread на основе вашей runnable, а затем вызываете bar.start(). Тогда ответственность JVM должна быть вызвана run() в этом отдельном потоке.

Пример:

 public class Foo<E> implements Runnable {
     private final E e;
     public Foo(E e) { ... }
     @Override
     public void run() {
         do something with e.
     }
 }

 Foo<String> foo = new Foo("hello");
 Thread bar = new Thread(foo);
 bar.start();