码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-09-19 00:33:48      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:逻辑   public   rgs   apple   通过   integer   pack   cas   类型信息   

在严格的泛型代码中,带有泛型声明的类总应该带着泛型参数,但为了与老的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)-泛型擦除与转换

标签:逻辑   public   rgs   apple   通过   integer   pack   cas   类型信息   

原文地址:https://www.cnblogs.com/shadow-shine/p/9672225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!