archie at dellroad.org
Fri Mar 14 23:34:15 UTC 2014
On Fri, Mar 14, 2014 at 9:57 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Regardless, "the JVM allows it, so the language should allow it" is
> barking up the wrong tree. The JVM and language have deeply different
> requirements, constraints, goals, and programmer audiences (the programmer
> audience for the JVM is mostly compiler writers.) The JVM has this
> flexibility not because we believe its a good idea to not initialize final
> fields, but because offline compilation is a better place to enforce this
> guideline than runtime.
I think the argument is more along the lines of: the JVM allows it, so if
the JLS does not allow it there ought to be a good reason.
A good reason would be e.g. "increases type safety".
But that is not the case here. Nothing that bothers you about the existing
semantics of how constructors work would be worsened by this change.
If you don't agree, please give an example so I can better understand you.
This "improvement" was deemed a bad idea in 2006 and is still a bad idea:
That bug is interesting because the counter-arguments presented in the
third comment (Alex Buckley 2006-11-21) can be completely countered by what
we've already discussed here: (1) the analysis complexity is exactly the
same as final fields, and the existing compiler code for that can be reused
easily; (2) the counter-argument to "purely semantic" applies just as
easily to final fields as it does to this proposal -- and look! we have the
compiler doing "semantic checking" of final fields currently -- so why the
> Just because a lot of other people had the same bad idea, doesn't mean its
> a good idea.
We agree on that principle.. but I don't agree that this is a bad idea. I
think it's a good idea and it should have been in the language from the
very start, as a parallel to what we have for final fields. It's
fundamentally the same thing, just with 'this' instead of 'field'. Again,
why should there be a double standard?
As far as I can see, the only real argument raised in favor of this feature
> is "the language already allows partially-constructed instances to be
> exposed to arbitrary code, how much worse would it be if it exposed
> even-less-constructed objects?" But this argument is a pretty silly one
> (it basically says that unless one can enforce a safety goal 100%, the goal
> has no legitimacy.)
I don't understand this and I'm not making that argument... can you please
show an example of where this change would allow exposure of a
less-constructed object than what the current JLS allows?
This seems to be a key area of disagreement and I'd like to better
understand what you're saying here. Please provide an example.
As I've said before, I don't even like that instances methods can be called
> from constructors, since they may still expose an object that has not been
> completely constructed. For example:
> Now suppose that the event source sends a message really soon after
> registration. B.onEvent() could see logger == null at line XXX. Ooops!
> What went wrong? A exposed a partially constructed B from its
> constructor, because the B initialization had not yet run when A's
> constructor registered itself as a listener, even though it thought it was
> all done initializing. B had no idea that A was a time bomb waiting to
> blow up. All because A was allowed to expose 'this' before it was finished
I actually agree with you here... the current rules may be too loose... and
this exact think has led to obscure bugs in Java code that I've worked on
over the years. Usually it involves the superclass constructor directly
invoking an instance method that the subclass overrides, and the subclass
override method uses instance fields that aren't initialized yet.
Ha! What's ironic is that the proposal under discussion would allow you to
address this problem: because the subclass could initialize it's final
fields prior to invoking super().
See, this change makes things better rather than worse :)
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the compiler-dev