打字猴:1.700447035e+09
1700447035 编写高质量代码:改善Java程序的151个建议 [:1700438167]
1700447036 编写高质量代码:改善Java程序的151个建议 建议94:不能初始化泛型参数和数组
1700447037
1700447038 泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码:
1700447039
1700447040 class Foo<T>{
1700447041
1700447042 private T t=new T();
1700447043
1700447044 private T[]tArray=new T[5];
1700447045
1700447046 private List<T>list=new ArrayList<T>();
1700447047
1700447048 }
1700447049
1700447050 这段代码有什么问题呢?t、tArray、list都是类变量,都是通过new声明了一个类型,看起来非常相似啊!但这段代码是编译通不过的,因为编译器在编译时需要获得T类型,但泛型在编译期类型已经被擦除了,所以new T()和new T[5]都会报错(可能有读者疑惑了:泛型类型可以擦除为顶级类Object,那T类型擦除成Object不就可以编译了吗?这样也不行,泛型只是Java语言的一部分,Java语言毕竟是一个强类型、编译型的安全语言,要确保运行期的稳定性和安全性就必须要求在编译器上严格检查)。可为什么new ArrayList<T>()却不会报错呢?
1700447051
1700447052 这是因为ArrayList表面是泛型,其实已经在编译期转型为Object了,我们来看一下ArrayList的源代码就清楚了,代码如下:
1700447053
1700447054 public class ArrayList<E>extends AbstractList<E>
1700447055
1700447056 implements List<E>,RandomAccess, Cloneable, java.io.Serializable
1700447057
1700447058 {
1700447059
1700447060 //容纳元素的数组
1700447061
1700447062 private transient Object[]elementData;
1700447063
1700447064 //构造函数
1700447065
1700447066 public ArrayList(){
1700447067
1700447068 this(10);
1700447069
1700447070 }
1700447071
1700447072 //获得一个元素
1700447073
1700447074 public E get(int index){
1700447075
1700447076 RangeCheck(index);
1700447077
1700447078 //返回前强制类型转换
1700447079
1700447080 return(E)elementData[index];
1700447081
1700447082 }
1700447083
1700447084 }
[ 上一页 ]  [ :1.700447035e+09 ]  [ 下一页 ]