当前位置: 首页 > 面试题库 >

Java如何实现内部类闭包?

祁高格
2023-03-14
问题内容

在Java中,匿名内部类可以在其局部范围内引用变量:

public class A {
    public void method() {
        final int i = 0;

        doStuff(new Action() {
            public void doAction() {
                Console.printf(i);   // or whatever
            }
        });
    }
}

我的问题是这实际上如何实施?如何实现i匿名内部doAction实现,为什么必须如此final


问题答案:

编译器会自动为您的匿名内部类生成一个构造函数,并将您的局部变量传递给该构造函数。

构造函数将此值保存在也称为的类变量(字段)中,该变量i将在“闭包”中使用。

为什么它必须是最终的?好吧,让我们探讨一下它不在的情况:

public class A {
    public void method() {
        int i = 0; // note: this is WRONG code

        doStuff(new Action() {
            public void doAction() {
                Console.printf(i);   // or whatever
            }
        });

        i = 4; // A
        // B
        i = 5; // C
    }
}

在情况A中iAction还需要更改字段,我们假设这是可能的:它需要对Action对象的引用。

假设在情况B中此实例Action垃圾回收的。

现在处于情况C:它需要一个实例Action来更新其类变量,但该值已被GCed。它需要“知道”它已被GC,但这很难。

因此,为了使VM的实现更加简单,Java语言设计人员曾说过,它应该是最终的,这样VM不需要一种方法来检查对象是否消失,并保证不修改变量,并且VM或编译器不必在匿名内部类及其实例中保留对变量的所有用法的引用。



 类似资料:
  • 数据层次结构是: < li >地点 < ul > < li>id < li >名称 < li >图像 < ul > < li >原稿_图像 < ul > < li>id < li >图像url < li >宽度 < li >高度 编号 image_url 宽度 高度 原始图像等于缩略图图像。 我的地方类是 我的图像课是 我的图像类是 当我编译这个项目时,房间库返回错误 错误:在com.test.r

  • 在阅读java Doc时,我得到了以下东西。 内部类C是类O的直接内部类,如果O是C的直接词汇封闭类,并且C的声明不发生在静态上下文中 所以如果我写信 我的问题是在这两个内部类中,哪一个是O的直接内部类? 我也有一些观点。 2.如果类O是C的第n-1个词汇封闭类的直接封闭类,则它是C的第n个词汇封闭类。 3.类O的直接内部类C的实例i与O的实例关联,称为i的直接封闭实例。对象的直接封闭实例(如果有

  • 问题内容: C ++具有多重继承。汇编级别的多重继承的实现可能非常复杂,但是在线上通常有很好的说明(vtable,指针修复,thunk等)。 Java没有多重实现继承,但是它确实具有多重接口继承,因此我认为每个类只有一个vtable的直接实现无法实现。java如何在内部实现接口? 我意识到与C++相反,Java是Jit编译的,因此不同的代码段可能会进行不同的优化,并且不同的JVM可能会做不同的事情

  • 问题内容: 我正在扩展ArrayList来创建一个自定义ArrayList,可以在迭代它的同时使用常规ArrayList方法进行修改。为此,我还要创建一个迭代器。 在我的hasNext()和next()方法期间,我需要确保列表没有被修改(可以在任何其他时间修改)。因此,我需要在我的shared()块中引用我的封闭类型。 问题答案: 。因此,在您的情况下,它将为。

  • 实例内部类是指没有用 static 修饰的内部类,有的地方也称为非静态内部类。示例代码如下: 上述示例中的 Inner 类就是实例内部类。实例内部类有如下特点。 1) 在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例。 2)在实例内部类中,可以访问外部类的所有成员。 提示:如果有多层嵌套,则内部类可以访问所有外部类的成员。 3)在外部类中不能直接访问内部类的成员,而必

  • 我有一个活动,有一些相同类型的片段。我有一份清单。只要我点击一个列表项,我就需要调用一个activity方法,传递点击发生的片段。 我认为这是一个相当愚蠢的问题,但我搞不懂。