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

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

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,编写部分函数会便利许多)