萌萌の初音
萌萌の初音
发布于 2023-02-24 / 1289 阅读
0

java调用kotlin的Unit回调方法

在android老项目维护中,新功能用kotlin来进行编写,当遇到java调用kotlin方法时也是非常轻松的事情,但kotlin的语法糖在java中使用有时也会造成一些麻烦,比如:

    fun demo0(block: () -> Unit) {
        block()
    }

以上代码可以让我们省去接口类的编写,快速的写出一个方法的回调,但在java使用就会报错,IDE不会去自动补全它,如果没仔细看提示可能就开始炫接口类了(苦笑),kotlin已经为我们提供好了方法,有23个方法供我们使用,上面的示例如何用java实现呢?如下:

        TestUnit.demo0(new Function0<Unit>() {
            @Override
            public Unit invoke() {
                return null;
            }
        });
        
        //lambda
        TestUnit.demo0(() -> null);

实现接口来自Function的重写方法返回null即可,就是这么简单。

那Unit有回调值咋解决?如下:

    fun demo1(block: (Boolean) -> Unit) {
        block(true)
    }

这是一个有布尔值的Unit方法,在java如下调用:

        TestUnit.demo1(new Function1<Boolean, Unit>() {
            @Override
            public Unit invoke(Boolean aBoolean) {
                return null;
            }
        });
  
        //lambda
        TestUnit.demo1(aBoolean -> null);

invoke多了一个布尔值的参数,很简单就实现了,那有多个参数咋整?开头就说了有23个方法,这些方法都是对应了不同数量的参数而实现的,比如

    fun demo2(block: (String, Int, List<String>, Long) -> Unit) {
        block("hello world", -1, listOf(), 1000L)
    }

在java中

        TestUnit.demo2(new Function4<String, Integer, List<String>, Long, Unit>() {
            @Override
            public Unit invoke(String s, Integer integer, List<String> strings, Long aLong) {
                return null;
            }
        });

那我超过了这么多参数如何实现呢?这就可以继承FunctionN接口类进行自己的实现,想加多少就加多少(得意)~

    //重写的接口类
    interface Function100<in P1, in P2, in P3, in P4, in P5, in P6, in P7, in P8, in P9, in P10, in P11, in P12, in P13, in P14, in P15, in P16, in P17, in P18, in P19, in P20, in P21, in P22, in P100, out R> : FunctionN<R>

    //实现方法
    fun demo100(block: (String, Int, List<String>, Long, String, String, String, String, String, String) -> Unit) {
        block("hello world", -1, listOf(), 1000L, "hello world", "hello world", "hello world", "hello world", "hello world", "hello world")
    }

在java中使用:

        TestUnit.demo100(new Function100<String, Integer, List<String>, Long, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, Unit>() {

            @Override
            public Unit invoke(Object... objects) {
                return null;
            }

            @Override
            public int getArity() {
                return 23;
            }
        });

新增了一个getArity()重写方法,用于超过22个参数后,定义invoke(Object… objects)的objects长度,使用参数Object object = objects[1]获取参数即可。