JLS tweaks

Remi Forax forax at univ-mlv.fr
Tue Mar 4 08:38:48 UTC 2014


Hi Archie,

On 03/03/2014 09:55 PM, Archie Cobbs wrote:
> Brian,
>
> Thanks for your comments.
>
> On Mon, Mar 3, 2014 at 11:45 AM, Brian Goetz <brian.goetz at oracle.com 
> <mailto:brian.goetz at oracle.com>> wrote:
>
>     *Idea #2: Allow non-this code prior to super()/this() call in
>     constructors*
>     This is well-traveled ground; this request has come up, and been
>     shot down, many times.  If anything, the language spec is already
>     too loose here, allowing too many unsafe operations (e.g., calling
>     virtual methods from constructors, allowing constructor to publish
>     'this', etc) and this would make this problem dramatically worse.
>
>
> I would like to better understand what you're saying here. I am 
> certainly not interested in changes that would weaken language safety, 
> so I must be misunderstanding something.
>
> When you refer to calling virtual methods and publishing 'this', do 
> you mean prior to superclass constructor invocation? If so how is that 
> possible currently? Because the JVM spec seems to disallow 
> <http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.2.4> 
> it..  I'm referring to the sentence "Before that method invokes 
> another instance initialization method of |myClass| or its direct 
> superclass on |this|, the only operation the method can perform on 
> |this| is assigning fields declared within |myClass|." I take this to 
> mean that for example that you couldn't pass 'this' as a parameter, 
> assign it to a field, invoke a method on it, or do anything else that 
> would allow its uninitialized escape.
>
> Or, if you meant calling virtual methods and publishing 'this' after 
> super()/this(), then how does this proposal have any relation to those 
> problems? They are on the "other side" of super()/this() line, so to 
> speak, and this proposal would not make them any more permitted than 
> they already are.
>
> It seems like the JVM spec gets it right - i.e., you can do (mostly) 
> whatever you want prior to super()/this() as long as it doesn't try to 
> make use of an uninitialized 'this', and no uninitialized 'this' can 
> escape. It seems reasonable to want the JLS to more closely mirror 
> this sensible stance.
>
> I must be missing something...

The rules of Java the language are less permissive than the rules of the 
JVM regarding uninitialized instance, that's true.
But at least, the Java rules is simple to understand to anyone. Adding 
complexity here will not worth it and as Brian mention,
you can still call a static method inside this() or super().

>
>     *Idea #3: Allow generic type declarations wherever normal type
>     declarations are allowed*
>     Obviously "wherever normal type declarations" is broader than you
>     mean.  What you're looking for is the ability to "uncapture" a
>     captured variable, giving it a name. As you've pointed out,
>     generic methods already provide you the ability to do that, and
>     what you're asking for is do to that 'inline' in a block of code. 
>     My recommendation is to try and take this to the next step (a more
>     detailed analysis); I think you'll find you'll run into complexity
>     at multiple levels.
>
>
> I may not be smart enough to actually reach those multiple levels of 
> complexity... :) Can you give me an example?
>
> In case it wasn't already clear... the original simplistic thought was 
> that at any variable declaration where the declared type is generic, 
> you could have the option of piggybacking onto that a generic type 
> variable declaration.
>
> So any:
>
> final List<?> x = ...
>
> could be changed to:
>
> final <T> List<T> x = ...
>
> and the T would be declared as a bound type variable with the same 
> scope as 'x'.

What you want is know as 'existential type', wildcards [1] are already a 
reduced form of existential types,
and as far as I know, nobody tries to unify the two concept in a sound 
framework.

>
>     *Idea #5: Allow enum types to have generic type parameters*
>     Another frequent suggestion.  I agree it would have been better if
>     it were done this way initially, and the cost would have been
>     low.  The cost of doing this now in a binary-compatible way would
>     be higher.
>
>
> Ah, I didn't realize there was a binary compatibility problem here. 
> What specifically is the problem?


There is another problem. You don't want an enum in your example.
You want some properties of an enum but not others. An enum in Java is 
not only a type of a serie of values,
it's a serie of values with a name, a unique number, a common type and a 
way to get an array of all these values (with Foo.values()).

In your example, you don't want a common type and if an enum type is a 
generic type values() will return array of wildcard making values() (and 
valueOf) useless from the typing point of view. It seems you want only 
one part of the enum and not the other, so an enum is the wrong language 
construction for your problem.

BTW, having the method values() also disable an enum to inherit from 
another one.

>
> Thanks,
> -Archie
>
> -- 
> Archie L. Cobbs

cheers,
Rémi

[1] http://www.sato.kuis.kyoto-u.ac.jp/~igarashi/papers/variance.html



More information about the compiler-dev mailing list