简体   繁体   中英

Why does Java claim 1.5 version need to be backward compatible?

Java 1.5 was released with Generics and they wanted it to be backward compatible with earlier versions and hence Java disallowed usage of method specific generics when creating raw instances.

for eg.,

class A<T> {
    <U> U myMethod(U u) {
        return u;
    }
}

If I do ,

A a = new A();

a.myMethod will ask me to pass Object as input and it's return type is Object. Clearly class type parameter 'T' doesn't conflict with myMethod() specific generic which is 'U'. But somehow java said, to handle backward compatability they erase the usage of all generics for raw instances.

The above question is asked multiple times by others and all the answers revolve by saying, because of Backward compatability with earlier versions java disallowed it. [DOT].

But none of the answers provided an instance what could have failed in earlier versions in case java allowed the usage of method specific generics for raw instances.

Can anyone help here by providing one specific instance where the problem would have occured in earlier versions prior to 1.5 if they have allowed it?

Please do not provide any other stackoverflow question's which doesn't have answer related to what could have failed.

Consider a Java program that was written to use Java collection types prior to Java 1.5.

Prior to Java 1.5, I would write

 List l = new ArrayList();
 l.append("Hello");
 l.append("World");
 String hello = (String) l.get(0);

Now with the type erasure model, I can compile that code in Java 1.5 or later ... without even a compiler warning. But I can also use the exact same collection classes in the modern way; eg

 List<String> l = new ArrayList<>();
 l.append("Hello");
 l.append("World");
 String hello = l.get(0);

And note that I am using the same classes and interfaces in both examples.

Without the erasure model to paper over the cracks, the Java designers would have had to create a parallel set of classes and interfaces for collections; ie

  • Pre-1.5 collections without generics and type parameters
  • Post-1.5 collections with generics and type parameters

Since the Java type equivalence is based on type names / identity rather than signature-based (or duck typing) equivalence, those two collection hierarchies would be incompatible. That would mean that APIs and implementations that used collections would need to choose between pre-1.5 and post-1.5 collections. Mixing them would be awkward ... and inefficient.

The end result would have been a big problem for people / organizations who needed to use legacy Java libraries and applications. Basically, migrating to Java 1.5 would have meant a lot of rewriting of applications that worked just fine. That would have killed generics, and Java as an enterprise language.


We cannot give you specific examples that provably wouldn't work in a Java language where generics were template based and / or there wasn't erasure.

  • That hypothetical Java language does not exist.
  • Given enough developer effort, any pre-1.5 Java program could have been ported to such a language.

When adding generics to the Java Language, the Java team wanted to satisfy the following requirements (among others):

  • Code compiled for Java 4 and code compiled for Java 5 must be able to coexist in the same JVM, and interact seamlessly
  • Library code written for Java 4 must be able to be ported to Java 5 in a way that does not break binary compatibility

Together, these requirements ensure that existing Java code can be ported incrementally and independently to the new language version, ensuring its widespread adoption with a minimum of disruption in the Java ecosystem.

The main difficulty arose from retrofitting the Java API's collection framework with generics in a way that did not break existing code. For instance, consider a Java 4 library that declares:

public List getFactories();

and is used in an existing Java 4 application that does:

List list = getFactories();

Now suppose the application is updated to Java 5 before the library is. What type parameter do they specify? They could say:

  • List factories = getFactories();

    ... but that denies new code the opportunity to use generics

  • List<Object> factories = getFactories()

    ... but that doesn't get rid of the unnecessary casts in application code - what good are generics if those remain? In addition, once the library does specify a type parameter, the application code would have to be updated a second time to match it.

  • List<Factory> factories = getFactories();

    ... but that would not be type safe: since the runtime was not told the type parameter when the List object was created, it is not able to verify that the List only contains factories (or enforce that this remains the case as legacy code continues to interact with the List )

  • List<Factory> factories = new ArrayList<Factory>(getFactories);

    ... which would work, but copying the entire list can be slow

The Java team chose option 3, and partially mitigated the impact by requiring the compiler to warn about the lack of type safety, and having the compiler insert synthetic casts to check the type of each individual object in the list before use, thereby preserving the integrity of the runtime type system at a slight cost to performance (and a significant cost of developer sanity when such a cast failed).

It is interesting to note that the C# design team, which was faced with essentially the same quandary when introducing generics to C# and the CLR a few years earlier, had opted to break backwards compatibility to reify generic types. As a consequence, they had to introduce an entire new collection framework (rather than simply retrofitting the existing collection framework as Java did).

In retrospect, I think the .NET team made the better choice here, because it allowed them to evolve the language rather than perpetuating its limitations. At least, the rationale for their design decisions doesn't need explaining a decade later :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM