Java 泛型详解

1.泛型出现的背景

JAVA推出泛型以前,程序员可以构建一个元素类型为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型,否则很容易引发ClassCastException异常。

2.泛型的理解和好处

使用传统方法的问题(不使用泛型)
(1)不能将加入到几个中的数据类型进行约束(不安全),进行转型可能会出现ClassCastException
(2)遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响

3.什么是泛型?

(1)泛型,即参数化类型。可以理解为,广泛的类型,可以表示数据类型的数据类型。是jdk5.0出现的新特性,用于解决数据类型的安全性问题。
(2)我们平时用的ArrayList就使用了泛型,List<T> list = new ArrayLIst<>();
①其中,T不代表值,而是表示类型
②任意字母都可以。常用T表示,是Type的缩写
(3)泛型把运行时异常,转到了编译时异常。只要程序编译时没有问题,就不会产生ClassCastException。
(4)泛型可以在类声明时通过一个标识表示类中某个属性的类型,或者某个方法的返回值的类型,或者是参数类型

public class Person<E> {
	E s; //E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
	public Person(E s){ //E也可以是参数类型
		this.s = s;
	}
	public E f(){ //返回类型使用E
		return s;
	}
}

4.泛型的定义与使用

(1)泛型的说明
interface 接口<T>{}class 类<K,V>{}
说明:
①其中T,K,V不代表值,而是表示类型(只能是引用类型,不能是基本数据类型)
②任意字母都可以。常用T表示,是Type的缩写
③在给泛型指定具体类型后,可以传入该类型或者子类类型
(2)泛型的实例化要在类名后面指定类型参数的值(类型),如:

List<String> strList = new ArrayList<String>();

(2)普通成员(属性,方法)可以使用泛型。静态成员(静态成员、静态方法)不能使用泛型(因为静态是和类相关的,在类加载时,对象还没有创建,泛型是在类创建的时候指定的)
(3)使用泛型的数组,不可以初始化

在这里插入图片描述

(4)泛型类的类型,是在创建对象时确定的,没有指定类型,默认为Object
例如:List list = new ArrayList(); 等价于 List<Object> list = new ArrayList<Object>();

4.1 泛型类

(1)泛型类的定义语法

class 类名称 <泛型标识1,泛型标识2,…> {
  private 泛型标识1 变量名; 
  private 泛型标识2 变量名; 
  .....
}

(2)泛型类的使用语法
①类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();
②Java1.7以后,后面的<>中的具体的数据类型可以省略不写
(3)泛型类的注意事项
①泛型类,如果没有指定具体的数据类型,此时,操作类型是Object
②泛型的类型参数只能是类类型,不能是基本数据类型
③泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型
(4)从泛型类派生子类
①子类也是泛型类,子类和父类的泛型类型要一致

class 子类<T> extends 父类<T> 

②子类不是泛型类,父类要明确泛型的数据类型

class 子类 extends 父类<指定类型>

4.2 泛型接口

(1)泛型接口的定义

interface 接口名称 <泛型标识1,泛型标识2,…> {
  泛型标识1 方法名(); 
  泛型标识2 方法名();
  .....
}

(2)泛型接口的使用
①实现类不是泛型类,接口要明确数据类型
②实现类也是泛型类,实现类和接口的泛型类型要一致
③泛型接口的类型,在继承接口或者实现接口时确定

4.3 泛型方法

①泛型类,是在实例化类的时候指明泛型的具体类型。
②泛型方法,是在调用方法的时候指明泛型的具体类型

(1)语法

修饰符 <泛型列表T,E,...> 返回值类型 方法名(参数){
   方法体...
}
public <T> void fly(T t) { } 

(2)使用
①修饰符与返回值中间泛型列表非常重要,可以理解为声明此方法为泛型方法。
②只有声明了泛型列表的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
④与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。

(3)注意
下面run方法不是泛型方法,而是使用了“类声明的泛型”

class Dog<T>{
	public void run(T t) { }
 }

4.4 泛型通配符

(1)<?>: 支持任意泛型类型
(2)<? extends A>:支持A类以及A类的子类,规定了泛型的上限
(3)<? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值