泛型(10)-泛型擦除与转换

Posted shadow-shine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型(10)-泛型擦除与转换相关的知识,希望对你有一定的参考价值。

在严格的泛型代码中,带有泛型声明的类总应该带着泛型参数,但为了与老的Java代码保持一致,也允许在使用带泛型声明的类时不指定实际的类型,如果没有这个泛型指定实际类型,此时被称作raq type(原始类型),默认时声明该泛型形参
时指定的第一个上限类型.

package com.j1803;


class Apple<T extends Number>{
private T size;

public Apple(T size) {
this.size = size;
}

public T getSize() {
return size;
}

public void setSize(T size) {
this.size = size;
}
public Apple(){

}
}

public class ErasureTest {
public static void main(String[] args) {
Apple<Integer> ig=new Apple<>(45);
//iggetSize()方法返回Integer类型对象
Integer as=ig.getSize();
System.out.println(as);

//ig赋值给Apple变量,丢失尖括号里的类型信息
Apple a=ig;
//a只知道size的类型是Number;
Number nm=a.getSize();
//下面代码引起编译错误a.getSize():java.lang.Number. ig1:java.lang.Integer
// Integer ig1=a.getSize();
}
}
上面程序定义了一个带有泛型声明的类AppLe类,其泛型形参的上限是Number,这个泛型形参用来定义Apple类的size变量.当把带有泛型信息的对象赋值给一个不带泛型信息的变量时,编译器就会丢失原来对象的泛型信息,也就是尖括号
里的信息都会丢失,因为Apple的泛型形参的上限是Number类,所以编译器依然知道a的getSize()返回的是Number类型,但具体是Number的哪个子类就不清楚了



从逻辑上来看,List<String>是List的子类,如果直接把List对象赋给一个List<String>对象应该会引起编译错误,但实际不会.对泛型而言,可以直接把一个List对象赋给一个List<String>对象,仅仅提示"未经检查的转换",
package com.j1803;

import java.util.ArrayList;
import java.util.List;

public class ErasureTest2 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
List list1=list;
List<String> ls=list1;
//运行时提示报错
System.out.println(ls.get(0));
}
}
java.lang.Integer cannot be cast to java.lang.String
Java允许直接把List对象赋给一个List<Type>(Type可以是任何类型)类型的变量,所以程序编译通过,但对于list变量实际上引用的是List<Integer>集合,所以当试图把该集合里的元素当成String类型的对象取出时,将引发
ClassCastException异常.
 

































































以上是关于泛型(10)-泛型擦除与转换的主要内容,如果未能解决你的问题,请参考以下文章

27.Android架构-泛型擦除机制

Java泛型擦除——以super关键字指定类型下限的在泛型擦除时会被擦成啥样的呢?

Java泛型擦除

Java 泛型使用上下边界通配符解决泛型擦除问题

Java中泛型区别以及泛型擦除详解

深入理解 Java 泛型擦除机制