Java 中的嵌套函数

2022-08-31 15:35:39

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);
    }
}

答案 1

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
}

该语法适用于仅定义一种方法的任何接口。因此,您可以将其与 一起使用,但它不适用于 .() ->RunnableList

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

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


答案 2

下面的答案是在谈论在Java 8之前在Java中拥有嵌套函数的最接近的方法。这不一定是我处理相同任务的方式,这些任务可能在JavaScript中使用嵌套函数进行处理。通常,私有帮助程序方法也可以很好地执行 - 甚至可能是私有帮助程序类型,您可以在该方法中创建其实例,但该类型可用于所有方法。

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


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

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

因此,为了(可怕的)歪曲你的例子:

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];
        }
    }
}

输出:

2
4
10
100

这是你从JavaScript代码中获得的输出吗?