Ahh, you missed the `lazy` keyword on there :-) Which is good because it raises an issue: when you forget it, bad performance may result without other observable consequence. Although, it's already the case that reading code like the above ought to raise all kinds of alarm bells (e.g., now I want to go check which fields computeHashCode() might be referring to, and where /they're/ initialized), so I /should/ be looking for that `lazy` keyword to put my mind at ease. So maybe this is okay.

Well, "bad" is relative; it won't be any worse than what you do today with eager static fields.  But yes, I did drop the lazy there.

I assume that, unlike other field initializers, I'm safe to refer to/any/ other field regardless of how and where that field is initialized. Right?

I think you mostly are asking about instance fields.  It would be safe to refer to any other field, however, if you _read_ a lazy field in the constructor, it might trigger computation of the field based on a partially initialized object.  The compiler could warn on the obvious cases where this happens, but of course it can be buried in a chain of method calls.

The intersection with primitives is interesting. I assume it gets secretly created as an Integer? So there's a little extra hidden memory consumption.

For static fields, there's an obvious and good answer that is optimally time and space efficient with no anomalies: condy.  We desugar

    lazy static T t = e
    ...
    moo(t)

into

    // no field needed
    static t$init() { return ; }
    ...
    moo( ldc condy[ ... ] )

and let the constant pool do the lazy initialization and caching. JITs love this.

For instance fields, we have a choice; use extra space in the object to store the "already initialized" bit, or satisfy ourselves with the trick that String does with hashCode() -- allow redundant recomputation in the case where the initializer serves up the default value.

So I think the divide is not ref-vs-primitive but whether we are willing to take the recomputation hit when it serves up a default value.


Reply via email to