Один из способов сделать это состоит в том, чтобы вставить фактическую реализацию рассматриваемого значения в другой класс. Это будет окончательным, но на самом деле не будет создано до тех пор, пока класс не будет загружен, который откладывается до тех пор, пока он не понадобится. Примерно так:
public class MyClass
{
private static class Loader
{
public static final INSTANCE = new Foo();
}
Foo getInstance()
{
return Loader.INSTANCE;
}
}
Это будет лениво инициализировать Foo
, как и при желании.
Если вам абсолютно необходимо, чтобы Foo
была переменной экземпляра вашего класса верхнего уровня - я не могу придумать никакого способа сделать это. Как вы заметили, переменная должна быть заполнена в конструкторе .
На самом деле я не совсем уверен, как Scala справляется с этим, но я предполагаю, что он устанавливает переменную lazy val
в некоторый вид thunk , который заменяется реальным объектом при первом оценены. Scala, конечно, может сделать это, подавив обычные модификаторы доступа в этом случае, но я не думаю, что вы можете прозрачно сделать это в Java. Вы можете объявить поле, например, Future<Foo>
, который создает значение при первом вызове и кэширует его с этого момента, но он не является прозрачным по ссылкам, и по определению final
я не вижу способа обойти это.