Huston, we have a problem !
Joe Darcy
joe.darcy at oracle.com
Sun Mar 6 16:00:02 PST 2011
Greetings.
This vein of feedback is at least 18 months late:
http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002173.html
I am not going to engage in a debate over whether or not diamond should
be in JDK 7.
-Joe
Zdeněk Troníček wrote:
> My answer is here (I also post it on my blog at
> http://tronicek.blogspot.com/2011/03/do-we-really-need-in-diamond-operator.html):
>
> As you may know, one of new features of upcoming Java 7 will be the
> diamond operator. Purpose of the diamond operator is to simplify
> instantiation of generic classes. For example, instead of
> List<Integer> p = new ArrayList<Integer>();
>
> with the diamond operator we can write only
> List<Integer> p = new ArrayList<>();
>
> and let compiler infer the value of type argument. Nice simplification.
> But do we really need to write <>? Isn't new ArrayList() enough? In this
> article, I will describe the arguments of the <> proponents and explain
> why I think that these arguments are not very strong. However, I also
> describe arguments why we need <>.
>
> In Java 1.4, we had raw types only:
> List p = new ArrayList();
>
> Java 5 introduced generics:
> List<Integer> p = new ArrayList<Integer>();
>
> Many types in Java API were generified and even though we can still use
> generic types as raw types, there is no reason for this in Java 5 or
> newer. When generics were introduced, raw types were allowed for backward
> compatibility so that we could gradually and smoothly adopt generics. For
> example, code in Java 1.4 can be combined with new generic code because
> raw and generic types are allowed together. This is also expressed in the
> JLS (4.8 Raw Types):
>
> "The use of raw types is allowed only as a concession to compatibility of
> legacy code. The use of raw types in code written after the introduction
> of genericity into the Java programming language is strongly discouraged.
> It is possible that future versions of the Java programming language will
> disallow the use of raw types."
>
> Now let's go back to the diamond operator and ask again: "Do we really
> need <>?". The proponents of the <> syntax say that we need <> to preserve
> backward compatibility. Let's look at an example from the coin-dev
> conference:
>
> class Foo<X> {
> Foo(X x) { }
> Foo<X> get(X x) { return this; }
> }
>
> class Test {
> void test() {
> Foo<?> f1 = new Foo(1).get(""); //ok - can pass String where Object
> is expected
> Foo<?> f2 = new Foo<>(1).get(""); //fail - cannot pass String where
> Integer is expected
> }
> }
>
> This shows the difference between new Foo(1) and new Foo<>(1). Clearly,
> these two are different and if we changed the semantics of new Foo(1), it
> would break backward compatibility. But wait. Backward compatibility with
> what? Isn't line
> Foo<?> f1 = new Foo(1).get("");
>
> a little suspicious? It uses generic type in the left part and raw type in
> the right part. Although it is legal, it is probably either omission or
> malpractice. And its legality is probably only a side effect of "a
> concession to compatibility of legacy code".
>
> Let's go further and look at another example from the coin-dev conference.
> It shows the difference between raw type and parameterized type with the
> diamond:
>
> public class X<T> {
> public X(T t) { }
> public T get() { return null; }
>
> public static int f(String s) { return 1; }
> public static int f(Object o) { return 2; }
>
> public static void main(String[] args) {
> System.out.println(f(new X<>("").get()));
> System.out.println(f(new X("").get()));
> }
> }
>
> Let's play with the code a bit. Let's assume that there was a library with
> the X class:
>
> public class X {
> public X(Object o) { }
> public Object get() { return null; }
> }
>
> and some code that compiled against this library:
>
> public class Client {
> static int f(String s) { return 1; }
> static int f(Object o) { return 2; }
>
> public static void main(String[] args) {
> System.out.println(f(new X("").get()));
> }
> }
>
> Then, the library was generified:
>
> public class X<T> {
> public X(T t) { }
> public T get() { return null; }
> }
>
> and we compiled the client project against the generified version. Now, if
> we changed the semantics of new X("") to new X<String>("") (or new X<>("")
> with the diamond syntax), the code would behave differently. So, the
> answer to the title question is 'yes'. If we want to stay backward
> compatible, we need <> and we cannot put new X("") semantically equal to
> new X<>("").
>
> Another questions are how long can Java evolve and remain compatible with
> concessions to compatibility and whether newcomers to Java will appreciate
> this.
>
> Z.
>
More information about the coin-dev
mailing list