JAVA泛型详解

1. 泛型基本应用

  • 作用:解决数据类型的安全性问题,在代码编译期就可避免类转换异常的发生。
  • 主要原理:在类声明时通过一个标识标识类中某个属性的类型或者某个方法的返回值及参数类型
  • 注意事项:
    • 泛型的指定中是无法指定基本数据类型的,必须设置为一个类。
    • 泛型为包装类时,参数传递的是基本数据类型会进行自动装箱为包装类。
1. 泛型类定义
[访问权限] class 类名<泛型类型标识1,泛型类型标识2,.....,泛型类型标识n> {
	[访问权限] 泛型类型标识 变量名称;
	[访问权限] 泛型类型标识 方法名称(){}
	[访问权限] 返回值类型声明 方法名称(泛型类型标识 变量名称){} 
}

- 示例

// 一个类只指定一个泛型类型
public class User<T> {
	private T t;
	public T getter() {}
	public void setter(T t){}
}

// 一个类中指定多个泛型类型
public class Node<k,V> {
	private K key;
	private V value;
	
	public K getter() {}
	public void setter(V v){}
}

2. 泛型对象
User<Integer> user = new User<>();

2. 通配符

1. 泛型中的引用传递
  • 注意:泛型类型间存在继承关系,声明的泛型对象并不存在继承关系
public static void main(String[] args) {
    User<Integer> user = new User<>();
    user.setter(1);
    // 不能将User<Integer>类型传入User<Object>中,编译报错:无法传递,即使Integer继承Object
    function(user);
}

public static void function(User<Object> user){}
2. 任意泛型类型
// 可传入任意类型的User,但是不能操作传入的User对象
public static void function(User<?> user){}

// 可返回任意类型的User
public static User<?>function(){}
3. 错误的泛型对象
// 配符?为变量时,不能添加\修改元素,可删除、可获取
User<?> user = new User<>();

// 编译报错:capture of ?,只有null可以传入
user.setter("wang");

3. 受限泛型

1. 泛型的上限
  • 泛型上限使用extends关键字声明,表示泛型的类型可以是所指定的类型或者此类型的子类
  • 上限<? extends T>的集合不能添加或修改,只能get或删除,因为通配符?编译器不能知道其具体类型,添加或修改的元素可能和原集合中的元素类型无任何关系
  • 用于返回类型限定时(只要是T及其子类的泛型对象都可被返回,并且可从返回值中获取元素)
  • 用于参数类型限定时(传入的集合中的元素只能是T及其子类,但是无法确定具体类型,所有不能添加或修改传入的集合,只能接受null的传入)
1. 定义类:[访问权限] 类名称<泛型标识 extend 类> {}
2. 声明对象:类名称<? extends 类> 对象名称。
示例:
	1. 类定义时指定泛型上限 
		public class Info<T extends Number> {}
	此时,声明的泛型对象只能是Number及其子类,Info<Integer> info = new Info<>();	
	2. 设置方法只能接受某上限的泛型类型
		public void fun(Info<? extends Number> info){}
	此时,方法接受的泛型对象只能是Number及其子类。fun(info<Integer>);
	3.  Son extends Father extends Human
	List<? extends Father> list1 = new ArrayList<>();
	Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
	Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
	Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。
	// 要使用子类具体类型,必须强转
	Son son = (Son)list1.get(0);
2. 泛型的下限
  • 泛型下限使用supper关键字声明,表示泛型的类型可能是所指定的类型或者此类型的父类
  • super 用于参数类型限定时(传入的泛型对象的泛型类型只能是T及其父类,对super入参添加元素时只能添加T及其子类(如果允许添加父类,则泛型类型T可能会对应多个没有任何关系的父类))
  • super 用于返回类型限定时(返回的泛型对象类型只能是T及其父类,且获取时只能是Object接收)
1. 定义类:[访问权限] 类名称<泛型标识 supper 类> {}
2. 声明对象:类名称<? supper 类> 对象名称。

4. 泛型接口

  • 泛型接口定义完成后,定义泛型接口的子类有两种方式
    • 在子类的定义上声明泛型类型
    • 直接在接口中指定具体的类型
// 泛型接口
public interface Info<T> {}

// 实现方式一
public class InfoImpl<T> implements Info<T> {}

// 实现方式二
public class inforImpl implements Info<String> {}

5. 泛型方法

  • 泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是。
[访问权限] <泛型标识> 泛型标识 方法名称(泛型标识 参数名)
1. 通过泛型方法返回泛型类实例
  • 泛型方法返回泛型类实例,必须在方法的返回类型声明处明确的指定泛型标识
// <T extends Number>的含义:方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定
public static <T extends Number> info<T> fun(T t) {}
2. 使用泛型统一传入的参数类型
// 该方法的两个info对象的泛型类型必须一致,否则编译报错
public static <T> void fun(Info<T> i1,info<T> i2) {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值