跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Java 能把代码块当参数传递到其他方法并执行吗?
未分類
13 5 月 2020

Java 能把代码块当参数传递到其他方法并执行吗?

Java 能把代码块当参数传递到其他方法并执行吗?

資深大佬 : atfeel 11

public void Main(){      //在这里定义代码块,并传入 Test 方法里     Test(         delegate(){             //代码逻辑         }     ); }          public void  Test(dele a) {     invoke(a);////在这里执行传入的代码块 } 

这种写法类似 C#到委托,java 里能做到吗?

大佬有話說 (38)

  • 資深大佬 : yikuo

    可以传递一个 Runnable 对象

  • 資深大佬 : xizismile

    方式 1:用对象来包装逻辑传递给其它方法
    方式 2:用 java8 提供的函数式接口来实现

  • 資深大佬 : xiangyuecn

    delegate ? C#打死也不用这么难懂的玩意(主要是这个单词手写敲不出来),还不如定义一个 interface 来的统一实在。。。实际上还是 Action 、Func 随便定义随便用,随便当参数,虽然本质上还是 delegate

    java:interface,统一实在,没参数的用 Runnable 省去了一个 interface 定义

  • 資深大佬 : KentY

    java 的源代码需要编译才能在 jvm 里执行. 所以你不能传递一个动态的 string, 然后希望 java 执行它.
    java 可以动态读取源代码文件并编译成 class, 比如通过 JavaCompiler 编译, 然后再通过 reflection 执行编译好的 class 里的 method.但是我猜这不是你需要的.
    如果我没理解错的话, 你大概需要一个类似 callback 的东西, 如果 java 版本是 8+, 它提供了一些现成的接口, 也可以就定义一个 classFooCallback {delegate(){…}}, 然后传递 FooCallback fooCallback instead of “dele a” . 当执行的时候, fooCallback.delegate()就可以了.
    按一般来说, 你的 delegate method 需要参数, 否则意义不大.

  • 資深大佬 : chihiro2014

    可以传逻辑,例如使用 Function

  • 資深大佬 : xgfan

    这不就是传个函数进去吗……

  • 主 資深大佬 : atfeel

    @xiangyuecn interface 不灵活,还要定义,麻烦啊

  • 資深大佬 : MineDog

    lambda 表达式啊,前提是要函数式接口

  • 資深大佬 : luckyrayyy

    完全,可能你得自己做一些工作。你可以动态生成一个 class 然后执行,直接执行代码块的话就不太确定行不行了。

  • 資深大佬 : xiangyuecn

    @atfeel #7 不会,无参的直接用系统的 Runnable 不用定义。有参的自己写个,大不了参数全为 Object

  • 資深大佬 : ipwx

    Java 8 不是有语法糖么,配合 interface 可以 f(x -> x + 1) 之类的

  • 資深大佬 : ipwx

    不过我记得 java 8 lambda 最大的问题不是有没有语法糖,而是 exception 检查那套。。。

  • 主 資深大佬 : atfeel

    @xiangyuecn 你的方法看起来不错,能随便写个模型我看看吗,分水岭难于逾越
    谢谢

  • 資深大佬 : Febers

    遇到过同样的需求,在没有改写成 Kotlin 之前,使用的是 Runnable 然后手动调 run ;改写成 Kotlin 之后看起来还挺酷的:
    //定义
    var action: ()->Unit = { }
    //赋值
    action = {
    //some code
    }
    //调用
    action.invoke() //action()

  • 資深大佬 : xiangyuecn

    #13 没格式,自己格式化一下再看

    static class aaa{
    static void exec(Func<Integer, Boolean, String> func1, Runnable action1, Action<String,Object,Integer> action2) {
    String val=func1.call(123, true);
    action1.run();
    action2.call(val, new java.util.Date(), 456);
    }
    interface Action<T1,T2,T3>{
    void call(T1 a1,T2 a2,T3 a3);
    }
    interface Func<T1, T2, ReturnType>{
    ReturnType call(T1 a1,T2 a2);
    }
    static public void test() {
    exec(new Func<Integer, Boolean, String>(){
    @Override public String call(Integer a1, Boolean a2) {
    return a1+” “+a2;
    }
    },new Runnable() {
    @Override public void run() {
    System.out.println(“Runnable”);
    }
    },new Action<String, Object, Integer>() {
    @Override public void call(String a1, Object a2, Integer a3) {
    System.out.println(a1+” “+a2+” “+a3);
    }
    });
    }
    }

    Java 能把代码块当参数传递到其他方法并执行吗?

  • 資深大佬 : liyanggyang

    Consumer<T>:消费型接口(有钱咱就花)
    接收一个数据,并且处理这个数据,处理完成之后,
    不需要返回任何数据,直接输出
    con.accept();

    Supplier<T>:供给型接口(后勤)
    提供需要用到的数据
    sup.get();

    Function<T, R>:函数型接口(乾坤大挪移)
    接收 T 类型转换为 R 类型
    fun.apply();

    Predicate<T>:断言型接口(包公断案)
    判断对与错,把控 if 关卡

  • 資深大佬 : lff0305

    Java 有很多 Runtime Compiler, 比如 logback 在用的 Janino, 等等
    以前实现类似的功能用的是 JDK8 里带的 js 引擎, js 当字符串传过去 eval 就 OK

  • 資深大佬 : Jrue0011

    JDK8 以后 java.util.function 下的接口基本能满足大部分日常需求了

  • 主 資深大佬 : atfeel

    @Febers 我没用 Kotlin,还是 java

  • 主 資深大佬 : atfeel

    @xiangyuecn 感谢

  • 主 資深大佬 : atfeel

    @Febers 你的这个方法就是我想要的了

  • 主 資深大佬 : atfeel

    @Febers Runnable 的用法,能举个例子吗

  • 資深大佬 : gz233

    @liyanggyang 正解

  • 資深大佬 : no1xsyzy

    感觉没什么分水岭的,只要你不是动态逻辑(即执行的代码是编译时决定的),那就可以用对象实现闭包,甚至如果不需要闭包就传个匿名类就行。

    至于需要动态逻辑、动态构造代码并执行的,那需要重新来套 lexer, syntaxer, interpreter/compiler 等,而且手动拼装语句容易错,如果是远程给代码直接调用,不如直接用个 JVM 内的解释器。
    或者含泪实践格林斯潘第十定律。

  • 資深大佬 : Febers

    @atfeel #22
    Kotlin 代码的本质是,定义一个类型属于 () -> Unit 的变量,然后动态赋值,通过 invoke 方法执行,反编译 Kotlin 的字节码之后可以发现,其对应的 Java 类型是 Function0 接口,位于 kotlin.jvm.functions,仿照其写法

    //使用了 @FunctionalInterface 以使用 Lambda
    @FunctionalInterface
    interface Action {
    void invoke();
    }

    //定义与赋值
    Action action;
    action = () -> {
    //some code 1
    };
    //非 Lambda 写法
    action = new Action() {
    @Override
    public void invoke() {
    //some code 2
    }
    };

    //调用
    action1.invoke();

    使用 Runnable 的原因很简单,它是系统定义的一个 FunctionalInterface,而且很普通,调用 run 方法也跟多线程没有关系,把 Runnable 替换成上面的 Action,就可以少写一个接口

  • 資深大佬 : Febers

    个人觉得 Kotlin 的很多东西很有趣,学习 Kotlin 反编译之后的 Java 代码,基本上就是用 Java 如何实现 Kotlin 特性的工业化答案。
    这个问题很多同学都给了答案,重点在于:Java 是纯面向对象语言,一切方法参数都是对象(基本数据类型不谈),而匿名内部类的存在让我们可以使用 自定义方法的对象,虽然写法看起来比较啰嗦;引入 Lambda 之后的 Java 代码写起来更“函数式”了,但本质上还是使用对象的概念

  • 資深大佬 : Febers

    如果要深究到语言特性的话,对于这样的需求,Java 字节码层面支持是 invokedynamic 指令的引入,语法层面的支持是 Lambda 的引入

  • 資深大佬 : no1xsyzy

    @Febers #25 这个匿名子类的做法,swing 的样例代码里就有……

  • 資深大佬 : Febers

    @no1xsyzy #28

  • 資深大佬 : zclHIT

    functional interface

  • 資深大佬 : no1xsyzy

    @Febers #29 Java 7 的时候 Callback 的写法只有这样吧…… 我 Java 用得不多,也是老早的事了,GUI 的 handler 就差不多只能这么玩,哪像 Qt 用槽。

  • 資深大佬 : sandrew1945

    使用 Lambda,参考 vert.x
    “`
    vertx.executeBlocking(this::blockingCode, this::resultHandler);

    private void blockingCode(Promise<JsonObject> promise)
    {
    // do something
    }

    private void resultHandler(AsyncResult<JsonObject> ar)
    {
    // get result
    }
    “`
    其中 executeBlocking 是这样定义的
    “`
    <T> void executeBlocking(Handler<Promise<T>> var1, Handler<AsyncResult<T>> var2);

    public interface Handler<E> {
    void handle(E var1);
    }
    “`

  • 資深大佬 : aguesuka

    effctive java 3rd 44 优先使用标准的函数式接口

  • 資深大佬 : CoderGeek

    Functional

  • 資深大佬 : stevenkang

    推荐文章 [Java8 新特性学习-函数式编程]( https://blog.csdn.net/icarusliu/article/details/79495534)

  • 資深大佬 : gmywq0392

    exec

  • 主 資深大佬 : atfeel

    @Febers 完美,可以了,可以了,可以结贴了,感谢,非常感谢!!

  • 資深大佬 : kingiis

    你是想问 动态生成 java 代码 动态执行么
    不如切到 js 动态 js 倒是很容易

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具