延迟初始化不可变变量

Jea*_*ean 4 java constructor immutability

我一直在使用scala的lazy val习惯用法,我想在Java中实现类似的东西.我的主要问题是构造一些值我需要一些在对象构造时不知道的其他值,但我不希望以后能够改变它.原因是,我正在使用一个GUI库,它代表我实例化对象,并在创建我需要的所有东西时调用一个不同的方法,这就是我知道我需要的值.

以下是我尝试实现的属性:
*变量的不变性.
*在构造函数之外的其他一些方法中初始化.

我不认为这在Java中是可能的,因为只有final实现变量的不变性,final变量才能在构造函数之外初始化.

Java中最接近我想要达到的目标是什么?

And*_*yle 5

一种方法是将所讨论的值的实际实例化推送到另一个类中.这将是最终的,但是在加载类之前不会实际创建,这将延迟到需要时.类似于以下内容:

public class MyClass
{
    private static class Loader
    {
        public static final INSTANCE = new Foo();
    }

    Foo getInstance()
    {
        return Loader.INSTANCE;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将懒洋洋地初始化Fooas as和when when.

如果你绝对需要成为Foo顶级类的实例变量 - 我想不出任何方法可以做到这一点.正如您所指出的,必须在构造函数中填充变量.

事实上,我不确定Scala是如何解决这个问题的,但我的猜测是它将lazy val变量设置为某种thunk,在首次评估时它被实际对象替换.Scala当然可以通过破坏这种情况下的普通访问修饰符来实现这一点,但我认为你不能在Java中透明地做到这一点.您可以将该字段声明为例如Future<Foo>在第一次调用时创建值并从该点开始缓存它,但这不是引用透明的,并且通过final我的定义我看不到解决方法.