Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin垃圾收集强引用lambda_Kotlin - Fatal编程技术网

Kotlin垃圾收集强引用lambda

Kotlin垃圾收集强引用lambda,kotlin,Kotlin,MainActivity.kt: class MainActivity : AppCompatActivity() { private val printers = Printers() private val strongObject = object: Item { override fun print(): Int { return Log.e("MainActivity", "strongObject") }

MainActivity.kt:

class MainActivity : AppCompatActivity() {

    private val printers = Printers()

    private val strongObject = object: Item {
        override fun print(): Int {
            return Log.e("MainActivity", "strongObject")
        }
    }

    private val strongSAM = {
        Log.e("MainActivity", "strongSAM")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val localObject = object: Item {
            override fun print(): Int {
                return Log.e("MainActivity", "localObject")
            }
        }
        val localSAM = {
            Log.e("MainActivity", "localSAM")
        }
        printers.add(strongObject)
        printers.add(strongSAM)
        printers.add(localObject)
        printers.add(localSAM)
        findViewById<TextView>(R.id.content).setOnClickListener {
            printers.dump()
        }
    }

}
Printers.java:

public class Printers {
    List<WeakReference<Item>> list = new ArrayList<>();

    public void add(final Item item) {
        list.add(new WeakReference<>(item));
    }

    public void dump() {
        Log.e("Printers", "Size: " + list.size());
        for (final WeakReference<Item> item: list) {
            if (item.get() != null) {
                item.get().print();
            }
        }
    }
}
如果运行此程序,您将注意到垃圾收集器将垃圾收集strongSAM、localSAM和localObject。然而,strongSAM有一个强引用,如何对其进行垃圾收集

我尝试使用dex2jar和Luyten查看生成的类文件:


从生成的类中的类查看器中,strongSAM实际上是一个字段,并且具有强引用。

从类文件中可以看到,
strongSAM
的实际函数对象在实际需要符合SAM类型(即调用
printers.add(strongSAM)
)之前可能不会实例化。因此,SAM对象可能仅存在于
onCreate
方法的范围内。但是,即使在onCreate中实例化了SAM对象,它也被分配给字段strongSAM,因此它具有强引用。不,它被分配给局部变量
strongSAM
,该变量隐藏外部字段。请参阅反编译类文件的第7行(
MainActivityKt$sam$Item$f92c66a0 strongSam;
)。哦,您是对的,它没有分配。我很好奇为什么它会创建一个局部变量。可能是因为它无法将
分配给
函数0
变量。函数类型也可以符合其他SAM类型,因此您需要在某处创建它们。
public class Printers {
    List<WeakReference<Item>> list = new ArrayList<>();

    public void add(final Item item) {
        list.add(new WeakReference<>(item));
    }

    public void dump() {
        Log.e("Printers", "Size: " + list.size());
        for (final WeakReference<Item> item: list) {
            if (item.get() != null) {
                item.get().print();
            }
        }
    }
}
Size: 4
strongObject