Use Advanced Search to search the entire archive.
Email proposal to the core-libs-dev@openjdk.java.net
- From: Martin Desruisseaux <
>
- To:
- Subject: Email proposal to the
- Date: Mon, 20 Oct 2014 05:21:58 +0900
- Organization: Geomatys
Bellow is my email proposal for the
list
(I may edit again tomorrow). Is there any objection or change proposal?
Note the following risk: if we get an answer, I'm 100% sure that the
answer will be that such break of parameterized type safety in the core
JDK is a big no-no, with no excuse tolerated. Some peoples may be
surprised that a JSR group considered such idea seriously enough for a
debate, to the point of becoming reluctant to include anything coming
from such group in the JDK.
------------------------------------------------------------------------
Subject: Interpretation of parameterized type usage in a JSR
Hello all
My apologize for resorting to this mailing list for a question about an
external API. I'm doing that, with agreement from other members of the
JSR group, for a JSR which could possibly be proposed for inclusion in
the JDK in some future version. I'm seeking confirmation about whether
the following rule shall suffers no exception. In a nutshell (more
detailed explanation below), given the following method signature where
X, Y and Z are interfaces:
X<Y> foo();
I claim that it would be unacceptable to have the foo() method
implementation actually returning instances of X<Z> through
parameterized type erasure (ignoring cases like Collections.emptyFoo()
where object properties do not depend on the parameter type). I claim
that no "developer convenience" consideration can justify such breaking
of Java parameter type safety. Some other peoples have the point of view
that the developer should know what he is doing.
Details
In this discussion I use the standard Comparable<?> interface and its
Shortand Integerimplementations for familiarity, but the actual JSR
objects are different. Consider the following method:
<X,Y> Comparable<?> multiply(Comparable<X> x, Comparable<Y> y);
Let assume that the type of the return value is not necessarily the
type, or a subtype, or a super-type of any of the arguments. It may be
for example because the multiply method applies the Java rules of Binary
Numeric Promotion (JLS §5.6.2). Consequently, the return type use the
<?> wildcard since we can not express the actual return type as a
function of X and Y with the parameterized type syntax. This force the
users to cast as in the following example:
Short x = 3;
Short y = 4;
Integer r = (Integer) multiply(x, y);
For reasons out of scope of this email, some peoples want to use only
the base interface:
Comparable<Short> x = (short) 3;
Comparable<Short> y = (short) 4;
Comparable<Integer> r = (Comparable<Integer>) multiply(x, y); // Unsafe
cast
Some peoples in our JSR group feel very strongly against the <?>
wildcard in return value. They consider it as a sign of bad design (note
that I disagree - for me in this particular situation, it means "can not
be expressed by the current Java parameterized type syntax". A JDK
example of such case is Class.getEnclosingClass()). Some peoples are
pushing for the following method declaration:
<X,Y,R> Comparable<R> multiply(Comparable<X> x, Comparable<Y> y);
In the above method signature X, Y and R appear independents - our
relationship between (X,Y) and R is not expressed. Of course this method
is impossible to implement without "unsafe cast" warnings, and those
casts can not be proved to be safe. But that method signature allows
users to write:
Comparable<Short> x = (short) 3;
Comparable<Short> y = (short) 4;
Comparable<Integer> r = multiply(x, y);
The cast and the warning disappeared, which was the effect desired by
the promoters. But that method signature also let users write:
Comparable<Byte> r1 = multiply(x, y); // Wrong!
Comparable<Float> r2 = multiply(x, y); // Wrong!
Comparable<String> r3 = multiply(x, y); // Wrong!
etc...
Above code compile without warnings and can run, but will fail randomly
at some later point when the assigned variables will be used. This is
understood, but partisans of the later method signature said that
developers should know what they are doing. My point of view is that no
argument can justify to break the Java parameterized type safety that way.
Alternative exists (e.g. not using parameterized types at all, do
something similar to Class.cast(Object), etc.), but I would like to have
a confirmation - or a correction if I'm wrong - of the following:
* Public parameterized method which are impossible to implement
without unprovable "unsafe cast" warnings, and which are known to
break parameterized type safety, are unacceptable.
* There is nothing wrong in using the <?> wildcard in a return value
if the actual type can not be expressed by the Java parameterized
type syntax.
Regards,
Martin