Java中的嵌套函数

And*_*een 46 java nested function

是否有任何Java编程语言扩展可以创建嵌套函数?在许多情况下,我需要创建仅在另一个方法或for循环的上下文中使用一次的方法.到目前为止,我无法用Java实现这一点,即使它可以在Javascript中轻松完成.

例如,这不能在标准Java中完成:

for(int i = 1; i < 100; i++){
    times(2); //multiply i by 2 and print i
    times(i); //square i and then print the result
    public void times(int num){

        i *= num;
        System.out.println(i);
    }    
}
Run Code Online (Sandbox Code Playgroud)

Nea*_*rdt 44

Java 8引入了lambdas.

java.util.function.BiConsumer<Integer, Integer> times = (i, num) -> {
    i *= num;
    System.out.println(i);
};
for (int i = 1; i < 100; i++) {
    times.accept(i, 2); //multiply i by 2 and print i
    times.accept(i, i); //square i and then print the result
}
Run Code Online (Sandbox Code Playgroud)

() ->语法适用于任何定义一个方法的接口.所以你可以使用它,Runnable但它无法使用List.

BiConsumerjava.util.function提供的众多功能接口之一.

值得注意的是,在引擎盖下,这定义了一个匿名类并实例化它. times是对实例的引用.


Jon*_*eet 26

下面的答案是谈论在Java 8之前在Java中嵌套函数最接近的问题.这不一定是我处理Javascript中嵌套函数可能处理的相同任务的方式.私有帮助器方法通常也可以这样做 - 甚至可能是私有帮助器类型,您可以在方法中创建一个实例,但是所有方法都可以使用它.

在Java 8中,当然有lambda表达式是一个更简单的解决方案.


你最容易接近的是一个匿名的内部阶级.这与Java目前的关闭一样接近,尽管希望Java 8中会有更多的支持.

匿名内部类具有各种限制 - 与Javascript示例(或使用lambdas的任何内容)相比,它们显然相当冗长,并且它们对封闭环境的访问仅限于最终变量.

所以(可怕地)歪曲你的榜样:

interface Foo {
    void bar(int x);
}

public class Test {
    public static void main(String[] args) {
        // Hack to give us a mutable variable we can
        // change from the closure.
        final int[] mutableWrapper = { 0 };

        Foo times = new Foo() {
            @Override public void bar(int num) {
                mutableWrapper[0] *= num;
                System.out.println(mutableWrapper[0]);
            }
        };

        for (int i = 1; i < 100; i++) {
            mutableWrapper[0] = i;
            times.bar(2);
            i = mutableWrapper[0];

            times.bar(i);
            i = mutableWrapper[0];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2
4
10
100
Run Code Online (Sandbox Code Playgroud)

这是你从Javascript获得的输出吗?

  • @Andy:嗯,不仅如此 - 他们无法访问您感兴趣的方法中的变量,而嵌套函数则可以.关闭可以非常方便...... (11认同)
  • 私有帮助器方法(与内部函数相反)的唯一问题是它们通过使函数在预期范围之外可用来增加源代码的混乱. (10认同)

dei*_*rus 24

我认为在Java 7中最接近嵌套函数的方法不是使用匿名内部类(Jon Skeet上面的答案),而是使用其他很少使用的本地类.这样,即使嵌套类的接口在其预期范围之外也是可见的,并且它也不那么冗长.

使用本地类实现的Jon Skeet示例如下所示:

public class Test {
    public static void main(String[] args) {
        // Hack to give us a mutable variable we can
        // change from the closure.
        final int[] mutableWrapper = { 0 };

        class Foo {
            public void bar(int num) {
                mutableWrapper[0] *= num;
                System.out.println(mutableWrapper[0]);
            }
        };

        Foo times = new Foo();

        for (int i = 1; i < 100; i++) {
            mutableWrapper[0] = i;
            times.bar(2);
            i = mutableWrapper[0];

            times.bar(i);
            i = mutableWrapper[0];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2
4
10
100
Run Code Online (Sandbox Code Playgroud)