如果父类不能被垃圾回收,那么 Java 8 方法引用能否被垃圾回收?

4

如果我拥有

public interface Foo {
    public void oneMethod();
}

然后我有另一个类:

public class TestClass {

    SoftReference sr;

    public test() {
        doSomething(this::lalala);
    }

    public lalala() {

    }

    public doSomethingFoo(Foo foo) {
      sr = new SoftReference(foo);
      //can sr.get() ever return null?
    }
}

sr.get()是否可能返回null?

如果使用匿名内部类或非静态内部类而不是方法引用,也想知道其行为。


2
你应该使用WeakReferenceSoftReference会在旧代中停留,只要还有堆空间可用。 - Marko Topolnik
好的,很酷,谢谢,但是如果父级不被垃圾回收,方法引用可以被垃圾回收吗? - pranahata
1
从解糖方法引用产生的对象知道this对象,但反过来不行。因此,一旦您在自己的代码中放弃该方法引用,它就可以自由地进行垃圾回收。 - Marko Topolnik
1
让我重新表述@MarkoTopolnik所说的:如果您的特定应用程序和使用场景需要使用SoftReference,那么可以使用它,但在测试和调试期间,请改用WeakReference,因为除非内存不足,否则SoftReference对象不会被丢弃。 - Mike Nakis
1个回答

10

为方法引用创建的实例的生命周期并不取决于方法引用的目标。相反,如果您的方法引用针对特定实例,则只要方法引用实例可达,目标实例就无法被垃圾回收。

由于Java规范未指定如何创建和重用lambda表达式和方法引用实例,因此它们的寿命也未指定(请参见A:Does a lambda expression create an object on the heap every time it's executed?)。

在实践中,使用当前实现,不捕获任何值的实例将被记住并重用,并且因此与创建它们的类一样长。相反,捕获值的实例,例如this::lalala 捕获了this引用的值,不会被重用,并且一旦变得不可达就会被垃圾回收。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接