Java小技巧:利用局部函数来隐藏和保护函数

文章探讨了在编程时尽量使用局部变量而非全局变量的原因,包括安全性和维护性。随着Java8的引入,开发者可以通过Lambda表达式和函数式接口在方法内部定义局部函数,如Supplier,Consumer和Function,以限制函数的可见性和提高代码的封装性。此外,还提到了自定义函数式接口和柯里化来处理多参数的情况。
摘要由CSDN通过智能技术生成

有过一些开发经验的开发者应该都知道:尽量用局部变量,尽可能避免用全局变量。过于暴露的变量可能被滥用而导致安全问题,对于代码维护也造成一些麻烦(得仔细检查该变量是不是被很多地方用到,等等)。

那么对于函数/过程/方法呢?随着面向对象编程和一些模块化技术的普及,函数也可以隐藏起来,比如:

public class Demo {
    public static void main(String[] args) {
        fun1();
    }

    private static void fun1() {
        //...
    }
}

这里的fun1静态方法就只能在Demo类的内部可以使用。

但即便如此,实际开发中一个类的代码可能有几百上千行,那么一个private的方法的可见范围和C语言中的全局函数差不多了,但这个方法很可能只有一个地方用到,甚至可能是为这个地方定制的辅助方法,那么这个方法的可见范围是整个类就显得不合适了。

利用Lambda表达式在方法内部定义局部函数

在JavaScript中,我们可以利用function直接定义局部函数:

function main(){
    function fun1(){
        //...
    }
    fun1();
}

Java并不能在方法里直接定义方法,不过好在 Java 8 借鉴一些函数式语言引入了Lambda表达式和函数式接口,这样Java也可以定义局部函数。利用这些特性,上面的代码就变为了:

class Demo {
    public static void main(String[] args) {
        Runnable fun1 = () -> {
            //....
        };
        fun1.run();
    }
}

如果想定义带返回值的局部函数,可以用Supplier接口:

class Demo {
    public static void main(String[] args) {
        Supplier<Integer> fun1 = () -> {
            //....
            return 1;
        };
        Integer integer = fun1.get();
    }
}

如果是只接受参数无返回值的局部函数,则使用Consumer接口:

class Demo {
    public static void main(String[] args) {
        Consumer<Integer> fun1 = (Integer i) -> {
            //....
        };
        fun1.accept(1);
    }
}

而既要参数又要返回值的就使用Function接口:

class Demo {
    public static void main(String[] args) {
        Function<Integer, String> fun1 = (Integer i) -> {
            //....
            return "number:" + i;
        };
        String s = fun1.apply(1);
    }
}

如果出现多个参数的情况,可以定义自己的函数式接口:

interface Fun2<A, B, C> {
    C apply(A a, B b);
}

class Demo {
    public static void main(String[] args) {
        Fun2<Integer, String, String> fun1 = (Integer i, String s) -> {
            //....
            return s + i;
        };
        String s = fun1.apply(1, "number:");
    }
}

或者使用柯里化(Currying):

class Demo {
    public static void main(String[] args) {
        Function<Integer, Function<String, String>> fun1 = (Integer i) -> (String s) -> {
            //....
            return s + i;
        };
        String s = fun1.apply(1).apply("number:");
    }
}

(如果语言有过程类型支持,例如scala、kotlin,编写局部函数会方便很多)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值