Erasure


There is more than one way that Sun might have chosen to implement support for parameterized types. One possible way would have been to create a brand-new type definition for each type to which you bind a parameterized class. In binding to a type, each occurrence of a naked type variable in the source would be replaced with the bind type. This technique is used by C++.

For example, were Java to use this scheme, binding MultiHashMap to <Date,String> would result in the following code being created behind the scenes:

 // THIS ISN'T HOW JAVA TRANSLATES GENERICS: package sis.util; import java.util.*; public class MultiHashMap<Date,String> {    private Map<Date,List<String>> map =       new HashMap<Date,List<String>>();    public int size() {       return map.size();    }    public void put(Date key, String value) {       List<String> values = map.get(key);       if (values == null) {          values = new ArrayList<String>();          map.put(key, values);       }       values.add(value);    }    public List<String> get(Date key) {       return map.get(key);    } } 

Binding MultiHashMap to another pair of types, such as <String,String>, would result in the compiler creating another version of MultiHashMap. Using this scheme could potentially result in the compiler creating dozens of class variants for MultiHashMap.

Java uses a different scheme called erasure. Instead of creating separate type definitions, Java erases the parameterized type information to create a single equivalent type. Each type parameter is associated with a constraint known as its upper bound, which is java.lang.Object by default. Client bind information is erased and replaced with casts as appropriate. The MultiHashMap class would translate to:

 package sis.util; import java.util.*; public class MultiHashMap {    private Map map = new HashMap();    public int size() {       return map.size();    }    public void put(Object key, Object value) {       List values = (List)map.get(key);       if (values == null) {          values = new ArrayList();          map.put(key, values);       }       values.add(value);    }    public List get(Object key) {       return (List)map.get(key);    } } 

Knowing how parameterized types work behind the scenes is critical to being able to understand and use them effectively. Java contains a number of restrictions on the use of parameterized types that exist because of the erasure scheme. I'll discuss these limitations throughout this chapter. Each possible scheme for implementing generics has its downsides. Sun chose the erasure scheme for its ability to provide ultimate backward compatibility.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net