【问题标题】:What is the equivalent of Kotlin "by lazy" in Java?Java中“懒惰”的Kotlin等价物是什么?
【发布时间】:2018-04-19 16:16:48
【问题描述】:

我正在关注这篇文章 https://proandroiddev.com/detecting-when-an-android-app-backgrounds-in-2018-4b5a94977d5c 来实现 android 生命周期,但在一个遗留应用程序上具有 java 上的 Application 类。

如何在 java 中实现这个 kotlin 代码?

private val lifecycleListener: SampleLifecycleListener by lazy {
    SampleLifecycleListener()
}

我觉得这是一个愚蠢的问题,但我不熟悉延迟初始化,我不知道如何搜索这个问题,任何“延迟理论链接”也将受到欢迎。

【问题讨论】:

  • Lazy Initialization in Kotlin 比较 Java 和 Kotlin。 (对kotlin lazy 的简单网络搜索很容易找到,所以“不知道如何搜索”听起来像是“懒得去搜索自己”,没有双关语)
  • 看看这个问题:Lazy field initialization with lambdas (java 8)
  • 延迟加载未内置在 Java 中。您必须自己实现它(如下面的答案)或使用为您完成它的库(例如 Spring)。似乎有一个 Android 延迟初始化库,因为它是一种相当直接的代理技术。
  • @Andreas 你的链接是金子,谢谢你,我真的做了我的搜索,但主要结果是关于 lateinit 与 lazy 等。可能我没有输入你的建议,因为我认为它是关于如何以及何时使用延迟初始化的另一种解释,所以我可能忽略了它。也许你对听起来“不确定如何搜索”是真的,我尽量避免回答“先搜索再问!”没有有用的内容。不是你的情况,现在我对懒惰有了更多了解:)

标签: java android kotlin


【解决方案1】:
private SampleLifecycleListener sll;

public synchronized SampleLifecycleListener getSampleLifecycleListener() {
    if (sll == null) {
        sll = new SampleLifecycleListener();
    }
    return sll;
}

这样在调用 getter 之前它不会被初始化。

【讨论】:

  • 在get函数中synchronize怎么样?
  • @KingfisherPhuoc 对于多线程支持,synchronized 可能成本太高,所以持有者模式更好。请参阅Lazy Initialization in Kotlin 中的示例,其中也显示了 Java 示例。
  • @KingfisherPhuoc 有需要吗?该方法只会在 onCreate() 中调用,因为它只在 UI 线程上运行,所以不需要任何同步。
  • 谢谢,忘记添加同步了。
  • Kotlin 相对于 Java 的一个好处是它允许你进行惰性计算,同时仍然允许为空。
【解决方案2】:

如果您愿意,可以从 Java 中调用 Kotlin lazy

import kotlin.Lazy;

Lazy<SampleLifecycleListener> lazyListener = kotlin.LazyKt.lazy(() -> new SampleLifecycleListener()));
SampleLifecycleListener realListener = lazyListener.getValue();

【讨论】:

    【解决方案3】:

    从 Java 8 开始,你可以使用ConcurrentHashMap#computeIfAbsent() 来实现懒惰。 ConcurrentHashMap 是线程安全的。

    class Lazy {
        private final ConcurrentHashMap<String, SampleLifecycleListener> instance = new ConcurrentHashMap<>(1);
    
        public SampleLifecycleListener getSampleLifecycleListener() {
            return instance.computeIfAbsent("KEY", k -> new SampleLifecycleListener()); // use whatever constant key
        }
    }
    

    你可以像这样使用它

    SampleLifecycleListener sll = lazy.getSampleLifecycleListener();
    

    【讨论】:

    • 你不能在其他解决方案中使用锁吗?我觉得地图增加了一点开销。
    猜你喜欢
    • 2016-04-10
    • 2017-10-29
    • 1970-01-01
    • 2022-11-15
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    相关资源
    最近更新 更多