Static fields in specialized classes

Stephen Colebourne scolebourne at joda.org
Wed Oct 15 14:51:40 UTC 2014


On 15 October 2014 00:59, Brian Goetz <brian.goetz at oracle.com> wrote:
> (But of course, you're free to have a gut feeling without having thought about it at all.)

I'm afraid I'm not paid to think full time about the issues like you
are, but where I can and will speak up is where I have concerns about
the "feel of Java" in future proposals.

> Similarly, Foo<int> can't extend Foo<?>

That is deeply unappealing.

Given your explanation, I understand why it might be convenient to be
defined that way, but that doesn't make it desirable. It depends on
whether you view the "class" as just Foo or the whole of
Foo<int>/Foo<T>. In some pieces of code, the method is acceptable the
full type of Foo<String> or Foo<int>, but in other bits of code you
just want to accept any Foo. If I write a method

process(Foo<?>)

today in Java 8, I expect it to be able to process a Foo with any
generic (ie. I'm saying that I don't care about the generic parameter,
and just want to use the other aspects of the class). To argue that in
the future such a method will not be able to accept a Foo<int> (or any
other value type) is as I said, deeply unappealing, and in a
reasonable sense, not backwards compatible.

Obviously alternative designs are hard, given that you've gone a fair
way down the current specialism route. I believe that what I really
want is for values to behave in code as fast objects, not for values
to behave with all the quirks of primitives. (Primitives are bad,
special cases in most framework code, and this thread appears to be
expanding the scope of those bad, special cases, not reducing it).
After all, I see no reason not to use value types very widely if done
well, which means that as a library writer I can't predict whether my
user has generified by a T or a value.

> We could hide the existence of List<int>.class, but that would just make
> life harder for users, who would then have to jump through bigger hoops to
> reflect over the members of List<int> (which are different from the members
> of List<String>, even after erasure.)

Class members being a different type is a tricky problem after
specialization. But one option would appear to be that viewed through
Class, the type of the array is the standard Object[] with appropriate
boxing. Only if you view through an additional "Specialized" lens
would you get to see the difference. (I acknowledge that this would be
not be easy to arrange and have other knock on effects, but they may
be less surprising than what is proposed in this thread).

Perhaps what Ben, Paul and I are ultimately saying is that the concept
of the Class mapping to the piece of source code is valuable, and
shouldn't be lost.

As part of this, I don't consider it desirable to be able to overload like this:

process(Foo<String>)
process(Foo<int>)

but not:

process(Foo<String>)
process(Foo<Integer>)

It should be both or neither.

Stephen


More information about the valhalla-dev mailing list