`

Generics and arrays

    博客分类:
  • java
阅读更多

转自:http://weblogs.java.net/blog/alexfromsun/archive/2011/05/05/swing-better-world-generics-and-arrays

 

Posted by  alexfromsun   on May 5, 2011 at 2:37 PM EDT
Generics doesn't work well with arrays. Everybody knows that you can't create a generified array, but not many people really know what it was done this way. A nice article fromBrian Goetz   helped me to understand the problem when I studied the new features of JDK 5.

The arrays in java are covariant when generics are not. The following code clearly shows it:

        String stringArray[] = 
new
 String[
1
];
        
// compiles ok

        Object objectArray[] = stringArray;
        
// throws ArrayStoreException

        objectArray[
0
] = 
new
 Object();

        ArrayList<String> stringList = 
new
 ArrayList<String>();
        
// doesn't compile - incompatible types

        ArrayList<Object> objectList = stringList;

If a generfied program is compiled without a warning you can safely add an Object to your ArrayList of Objects. However when there is an array of Objects passed to your method as a parameter, there is no way to understand an object of what type you can put there (I am not sure if you can find it out via reflection). 
So it is known that arrays and generics don't do well together. It means that it is not recommended to use two features of JDK 5 together, I am talking about generics and  varargs .

This reminds me one old bug found by  Rémi Forax , which was fixed by changing

    
protected
 
void
 process(V... chunks) {
    }
to
    
protected
 
void
 process(List<V> chunks) {
    }
in the  SwingWorker   class, which did look awkward at the first glance.

An alternative implementation

I would be happy if I could create and safely use generified arrays in java, at the same time I can hardly remember if I ever saw a snippet of code that really benefited from the fact that arrays are covariant. This feature of java arrays doesn't look attractive to me and I don't mind "deprecating" it, I don't feel it is correct that I can't create a generifed array when I never cast an array of one particular type to an array of its supertype.


Certainly all java code must be backward compatible with any new version of JDK, I am thinking about a new warning produced by the compiler when covariant arrays are in use. If there is no such a warning in your code it should be pretty acceptable to create a generified array, otherwise you are warned just like when you use a raw type of a generifed class. Something to discuss for the next JDKs?

 

 

 

读后注:为什么要这样改参数呢?因为你已知数组与泛型支持不足,如果前者V是OBJECT,你如个STRING数组过去,这是编译不报错,但有隐含BUG,在方法内,你再以OBJECT对象去操作数组,这时就出错!而用后者LIST作参数,若V是OBJECT,然后你传个STRING的LIST,编译时就出错,很好地抵制隐含的BUG。这些论断已用程序验证过。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics