【问题标题】:Runnable with a method parameter可使用方法参数运行
【发布时间】:2018-04-14 10:48:55
【问题描述】:

Runnable 中是否可以有这样的方法参数:

public Runnable createRunnable(Method a_void_method) {
    Runnable runnable = new Runnable() {
        public void run() {
            //a_void_method
        }
    };
    return runnable;
}

或者有什么办法可以做到这一点?

【问题讨论】:

    标签: java


    【解决方案1】:

    Runnable 表示一个不带参数并返回void 的方法。如果您想表示一个接受参数的方法,请考虑使用ConsumerBiConsumer

    或者您可能在问如何将Consumer 转换为Runnable,试试这个:

    private static <T> Runnable toRunnable(Consumer<? super T> consumer, T parameter) {
        return () -> consumer.accept(parameter);
    }
    

    【讨论】:

      【解决方案2】:

      您正在创建的Runnable 与任何其他匿名嵌套类没有区别。因此,您可以将任何“有效最终”对象引用传递给它。在您的情况下,Method 参考就可以了。

      但是Method需要一个实例或class来操作,否则该方法不知道要调用哪个多态方法,也不知道要传递哪些数据。

      如果您的 Java 版本是 8 之前的版本,您需要将对象实例传递给您的 createRunnable

      public Runnable createRunnable(Object instance, Method method) {
         return new Runnable() {
             try {
                 method.invoke(instance);
                  } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                       // handle exception
                       throw new RuntimeException(e);
                  }
         };
      )
      

      在 Java-8 及更高版本中,您可以使用 lambda 方法引用,无需创建函数:

      Runnable r = () -> { 
                  try {
                      method.invoke(instance);
                  } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                       // handle exception
                       throw new RuntimeException(e);
                  }
              };
      

      或者,如果你已经知道方法和实例,你也可以使用

      Runnable r = object::method;
      

      【讨论】:

        【解决方案3】:

        如果你真的有一个通过反射得到的Method

         public void run() {
             a_void_method.invoke(instance_to_invoke_on);
             // or if method is static,
             // a_void_method.invoke(null);
         }
        

        否则,您可能正在寻找 lambda,尤其是 method references

        class X {
            void a_method() { ... }
        }
        
        X x = ...
        Runnable runnable = x::a_method;
        

        【讨论】:

          【解决方案4】:

          你可以使用 Runnable 来表示一个返回 void 的方法,不带这样的参数。

          public Runnable createRunnable(Runnable a_void_method) {
                  Runnable runnable = new Runnable() {
                      public void run() {
                          a_void_method.run();
                      }
                  };
                  return runnable;
          }
          

          或更紧凑的形式:

          public Runnable createRunnable(Runnable a_void_method) {
                return () -> a_void_method.run();           
          }
          

          或使用方法参考。

          public Runnable createRunnable(Runnable a_void_method) {
                 return a_void_method::run;
          }
          

          此外,您甚至可能不需要将 a_void_method 的逻辑包装在方法中,而是可以直接内联分配它:

          Runnable runnable = ClassName::a_void_method; 
          

          如果你想表示一个带参数的返回 void 的方法,请查看 ConsumerBiConsumerspecific specialization of it

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-28
            • 1970-01-01
            • 2013-12-24
            • 1970-01-01
            相关资源
            最近更新 更多