Java中的泛型

一、泛型概述

1.什么是泛型:

在Java中我们在声明方法时,当在完成方法功能时如果有未知的数据需要参与,而这些末知的数据需要在调用方法时才能确定,那么我们把这样的数据通过形参表示。在方法体中,用这个形参名来代表那个未知的数据,而调用者在调用时,对应的传入实参就可以了。受此启发,JDK1.5引入了泛型的概念,泛型即为类型参数,这个类型参数在声明它的类、接口或方法中代表未知的某种通用类型。

所谓泛型,就是允许在定义类、接口时通过一个"标识"表示类中某个'属性的类型'或者是某个方法的'返回值或参数的类型'。这个类型参数将在使用时(继承或实现这个接口、创建对象或调用方法时)确定(即传入实际的类型参数,也称为类型实参)。

2.在集合中使用泛型之前可能存在的问题

(1)类型不安全,因为add()操作的参数是Object类型,意味着任何类型的对象都可以添加成功

(2)需要使用强转操作,还有可能导致ClassCastException异常

3.使用方法:

List<Integer> list = new ArrayList<Integer>();
List<Integer> list = new ArrayList<>();
Map<String,Integer> map = new HashMap<String,Integer>();
Map<String,Integer> map = new HashMap<>();
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();

4.使用说明:集合框架在声明接口和其实现类时,使用了泛型,在实例化集合对象时,如果没有使用泛型,则认为操作的是Object类型的数据,如果使用了泛型,则需要指明泛型的具体类型,一旦指明了泛型的具体类型,则在集合的相关方法中凡是使用类的泛型的位置都替换为具体的泛型类型;

二、自定义泛型类和泛型方法

1.自定义泛型类\接口

(1)格式:

class 类名<T>{
    T t;
}
interface 接口名称<T1,T2>{

}

(2)使用说明:

a.声明了类的泛型参数以后就可以在类的内部使用此泛型参数;

b.实例化时就可以指明类的泛型参数类型,一旦指明了泛型参数的类型则在泛型类中凡是使用该泛型参数的位置都替换为该数据类型;

c.泛型参数在指明时不可以使用基本数据类型,但是可以使用包装类代替对应的基本数据类型;

d.如果在创建自定义泛型类的对象时,没有指明泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照Object处理,但不等价于Object;

e.除创建泛型类对象外,子类继承泛型类时以及实现类实现泛型接口时可以确定泛型结构中的泛型参数;如果我们在给泛型类提供子类时子类也不确定泛型的类型,则可以维续使用泛型参数;还可以在现有的父类的泛型参数的基础上新增泛型参数;

经验:泛型要使用就一路都用,要不用一路都不要用;

(3)注意点:

a.泛型类可能有多个泛型参数,此时应将多个泛型参数一起放在尖括号内;

b.JDK7.0开始,泛型的简化操作:ArrayList<Fruit>flist =new ArrayList<>();

c.如果泛型结构是一个接口或抽象类则不可创建泛型类的对象;

d.不能使用new E[]的结果,但是可以使用E[] elements = (E[]) new Object[capacity];

e.在类或接口上声明的泛型在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型;

f.异常类不能是带泛型的;

2.自定义泛型方法

(1)格式:

public <E> E method(E e){
    return null;
}
权限修饰符 [其他的一些修饰符] <T> 返回值类型 方法名(形参列表){
    通常在形参列表或返回值位置出现泛型参数T
    
}

(2)说明:

a.声明泛型方法时一定要添加泛型参数<T>;

b.泛型参数在方法调用时指明其具体的类型;

c.泛型方法可以根据需要声明为static的;

d.泛型方法所属的类与该类是否是一个泛型类无关

三、泛型在继承上的体现

1.类SuperA是类A的父类,则G<SuperA>和G<A>是并列的两个类,没有任何的子父类关系;

2.类SuperA是类A的父类或接口,则SuperA<G>和A<G>存在子父类关系,A<G>是SuperA<G>的子类或实现类,类A<G>可以赋值给SuperA<G>的引用;

四、通配符的使用

1.通配符:?

2.使用说明:

List<?> list= null;
List<Object> list1 = null;
List<String> list2 = null;
list = list1;
list = list2;

G<?>可以看做是G<A>类型的父类,即可以将G<A>的对象赋值给G<?>类型的引用(或变量)

3.读写数据的特点:

(1)读取数据:允许的,读取的值的类型为Object类型

(2)写入数据:不允许的,但是可以写入null值

4.有限制条件的通配符的使用:

(1)List<? extends A>:可以将List<A>或List<B>对象赋值给List<? extends A>,其中B类型是A类的子类;

(2)List<? super A>:可以将List<A>或List<B>对象赋值给List<? super A>,其中B类型是A类的父类;

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值