简体   繁体   中英

Why java type erasure is needed at runtime at all?

Below is an excerpt from java documentation here

Because of type erasure, List<Number> and List<String> both become List. Consequently, the compiler allows the assignment of the object l, which has a raw type of List, to the object ls.

Also from the same documentation

Consider the following example:

List l = new ArrayList<Number>();
List<String> ls = l;       // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0);      // ClassCastException is thrown

During type erasure, the types ArrayList and List become ArrayList and List, respectively.

Why compiler can't show this as an error (instead of warning). Could someone kindly help with an example where warning is needed and will cause an issue (or make certain useful patterns impossible) when warning becomes an error.

Java gained type variables in java 1.5. Before java 1.5, they did not exist .

Java also strongly dislikes releasing new versions such that 'upgrading' is more involved than just 'simply compile your existing code with the new compiler and it all just works exactly like it did before'. Also, 'you can run code compiled with the javac from java 1.4, on the java.exe from 1.5 and it runs fine'.

Why? Well, because otherwise you get a split community, and because most projects use 500 dependencies, that is hugely detrimental. You can't 'upgrade' from java 1.4 to 1.5 until each and every single last one of those 500 deps has upgraded.

Combine these 2 facts and generics makes sense:

  • Why erasure at all? Because how else could it work? Class files stemming from javac1.4 cannot possibly have the generics info, given that they did not exist when javac1.4 was released

  • Why 'raw types'? Because pre-generics code by their nature have them ( List<T> would be a compiler error on java 1.4), and by their nature, there is no sanity, typevar-wise. You could write this:

List foo = new ArrayList();
foo.add(5);
foo.add("hello");

and it compiles just fine on javac 1.4. Therefore it MUST also compile on javac 1.5 . As a compromise, if you attempt to compile that on javac from 1.5, it works and produces a class file that acts identically, but you do get warnings.

java 1.5 is now 25 years old or whatnot. So it all seems weird and archaic now. But you're asking 'why'. This is why.

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