196

「パラメータを受け入れるランナブル」が必要ですが、そのようなランナブルは実際には存在しないことは知っています。

これは、アプリの設計の根本的な欠陥や疲れた脳の精神的な障害を示している可能性があるため、基本的なOOの原則に違反せずに、次のようなことを達成する方法についてのアドバイスをここで見つけたいと思っています。

  private Runnable mOneShotTask = new Runnable(String str) {
    public void run(String str) {
       someFunc(str);
    }
  };  

上記のようなことを達成する方法はありますか?

4

9 に答える 9

247

さて、私が最初にこれを投稿してからほぼ9年が経ちましたが、正直なところ、Javaはそれ以来いくつかの改善を行ってきました。元の答えは以下に残しておきますが、そこにあることを人々が行う必要はありません。9年前、コードレビュー中に、なぜ彼らがそれを実行し、おそらく承認しなかったのか疑問に思いました。現代のラムダが利用可能であるため、時代遅れのアプローチを推奨するような非常に投票された回答を得るのは無責任です(公平に言えば、そもそも疑わしいです...)現代のJavaでは、そのコードレビューはすぐに拒否されます。提案:

void foo(final String str) {
    Thread t = new Thread(() -> someFunc(str));
    t.start();
}

以前と同様に、そのスレッドを意味のある方法で処理するなどの詳細は、読者の演習として残されています。しかし、率直に言って、ラムダを使用することを恐れている場合は、マルチスレッドシステムをさらに恐れる必要があります。

元の答え、理由は次のとおりです。

メソッドでクラスを宣言できます

void Foo(String str) {
    class OneShotTask implements Runnable {
        String str;
        OneShotTask(String s) { str = s; }
        public void run() {
            someFunc(str);
        }
    }
    Thread t = new Thread(new OneShotTask(str));
    t.start();
}
于 2011-05-02T03:17:52.703 に答える
52

あなたはそれを関数に入れることができます。

String paramStr = "a parameter";
Runnable myRunnable = createRunnable(paramStr);

private Runnable createRunnable(final String paramStr){

    Runnable aRunnable = new Runnable(){
        public void run(){
            someFunc(paramStr);
        }
    };

    return aRunnable;

}

(これを使用したとき、パラメーターは整数IDであり、ID-> myRunnablesのハッシュマップを作成するために使用しました。これにより、ハッシュマップを使用して、ハンドラー内のさまざまなmyRunnableオブジェクトを投稿/削除できます。)

于 2012-04-19T23:18:27.547 に答える
34
theView.post(new Runnable() {
    String str;
    @Override                            
    public void run() {
        par.Log(str);                              
    }
    public Runnable init(String pstr) {
        this.str=pstr;
        return(this);
    }
}.init(str));

オブジェクト自体を返すinit関数を作成し、それを使用してパラメーターを初期化します。

于 2013-05-23T17:49:25.667 に答える
17

Java 8以降、最良の答えは以下を使用することConsumer<T>です。

https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html

これは機能インターフェイスの1つです。つまり、ラムダ式として呼び出すことができます。

void doSomething(Consumer<String> something) {
    something.accept("hello!");
}

...

doSomething( (something) -> System.out.println(something) )

...
于 2020-01-09T09:21:12.077 に答える
11

Runnableインターフェイスを実装する次のクラスを使用します。このクラスを使用すると、引数を使用して新しいスレッドを簡単に作成できます

public abstract class RunnableArg implements Runnable {

    Object[] m_args;

    public RunnableArg() {
    }

    public void run(Object... args) {
        setArgs(args);
        run();
    }

    public void setArgs(Object... args) {
        m_args = args;
    }

    public int getArgCount() {
        return m_args == null ? 0 : m_args.length;
    }

    public Object[] getArgs() {
        return m_args;
    }
}
于 2014-01-30T15:42:00.273 に答える
10

2つのオプションがあります。

  1. 名前付きクラスを定義します。指定されたクラスのコンストラクターにパラメーターを渡します。

  2. 匿名クラスを「パラメータ」の近くに配置します。必ず。としてマークしてくださいfinal

于 2011-05-02T03:18:34.517 に答える
5

新しいRunnable()またはrun()に渡される引数が必要になるために、ここで何を達成しようとしているのかを最初に知りたいと思います。通常の方法は、開始する前にメンバー変数を設定することにより、データ(str)をスレッドに渡すRunnableオブジェクトを用意することです。次に、run()メソッドは、これらのメンバー変数値を使用してsomeFunc()を実行します。

于 2011-05-02T03:20:42.053 に答える
1
/**
 * @author AbdelWadoud Rasmi
 * <p>
 * The goal of this class is to pass some parameters to a runnable instance, a good example is
 * after caching a file you need to pass the new path to user to do some work on it.
 */
public abstract class ParameterizedRunnable implements Runnable {
    private Object[] params;

    /**
     * @param params: parameters you want to pass the the runnable.
     */
    public ParameterizedRunnable(Object... params) {
        this.params = params;
    }

    /**
     * Code you want to run
     *
     * @param params:parameters you want to pass the the runnable.
     */
    protected abstract void run(Object... params);

    @Override
    public final void run() {
        run(params);
    }

    /**
     * setting params
     */
    public void setParams(Object... params) {
        this.params = params;
    }

    /**
     * getting params
     */
    public Object[] getParams() {
        return params;
    }
}
于 2021-08-04T16:11:03.073 に答える
0

これまでの最善の方法:

Consumer<String> oneShot = str -> {
    
   somefunc(str);
    
};

oneShot.accept("myString");
于 2021-11-14T13:39:06.803 に答える