Java泛型通配符的使用

news2025/1/14 18:38:36

 

 

目录

泛型在继承方面的体现

 类A是类B的父类,G和G二者不具有子父类关系,二者是并列关系

类A是类B的父类,A是B的父类

通配符的使用

类A是类B的父类,G和G是没有关系的,二者共同父类是:G 

使用通配符后,数据的写入和读取要求

 有限制条件的通配符的使用

自定义泛型的测试

User类 

 DAO类

DAOTest


 

泛型在继承方面的体现

 类A是类B的父类,G<A>和G<B>二者不具有子父类关系,二者是并列关系

@Test
	public void test1() {
		Object obj=null;
		String str=null;
		obj=str;//编译通过
		
		Object[] arr1=new Object[10];
		String arr2[]=new String[10];
		arr1=arr2;//编译通过
		
		//此时的list1和list2不具有子父类关系
		List<Object> list1=null;
		List<String> list2=null;
		
		//编译不通过
		list1=list2;
		
		show(list1);
		//编译不通过
		show(list2);
	}
	
	public void show(List<Object> list) {
		
	}

类A是类B的父类,A<G>是B<G>的父类

@Test
	public void test2() {
		AbstractList<String> list1=null;
		List<String> list2=null;
		ArrayList<String>list3=null;
		
		list1=list3;//编译通过
		list2=list3;//编译通过
	}

通配符的使用

通配符?

类A是类B的父类,G<A>和G<B>是没有关系的,二者共同父类是:G<?> 

    @Test
	public void test4() {
		List<Object> list1=null;
		List<String> list2=null;
		
		List<?> list=null;
		
		list=list1;//编译通过
		list=list2;//编译通过
		print(list1);//编译通过
		print(list2);//编译通过
	}
	
	public void print(List<?> list) {
		Iterator<?> it=list.iterator();
		while(it.hasNext()) {
			Object obj=it.next();
			System.out.println(obj);
		}
	}

使用通配符后,数据的写入和读取要求

添加:对于List<?>就不能向其内部添加数据,除了添加null之外

获取:允许读取数据,读取的数据类型为Object

@Test
	public void test5() {
		List<?> list=null;
		List<String> list3=new ArrayList<>();
		list3.add("AAA");
		list3.add("BBB");
		list3.add("CCC");
		
		list=list3;
		//添加:对于List<?>就不能向其内部添加数据。
		//除了添加null之外
		
		list.add("DD"); //编译不通过
		list.add("?");	//编译不通过
		
		list.add(null);	//编译通过
		
		//获取:允许读取数据,读取的数据类型为Object
		Object obj = list.get(0);
		System.out.println(obj);
	}

 有限制条件的通配符的使用

 ? extends A:
       G<? extends A>可以作为G<A>和G<B>的父类,其中,B是A的子类

        G存储的是A和A的子类
 ? super Person:
        G<? super A>可以作为G<A>和G<B>的父类,其中,B是A的父类

        G存储的是A和A的父类

@Test
	public void test6() {
		List<? extends Person> list1=null;
		List<? super Person> list2=null;
		
		List<Student> list3=new ArrayList<>();
		List<Person> list4=new ArrayList<>();;
		List<Object> list5=new ArrayList<>();;
		
		list1=list3; //编译通过
		list1=list4; //编译通过
		list1=list5; //编译不通过
		
		list2=list3; //编译不通过
		list2=list4; //编译通过
		list2=list5; //编译通过
		
		//读取数据
		list1=list3;
		Person p = list1.get(0); //编译通过
		Student st=list1.get(0); //编译不通过
		
		list2=list4;
		Object obj = list2.get(0); //编译通过
		Person obj2=list2.get(0); //编译不通过
		
		//写入数据
		list1.add(new Student()); //编译不通过
		
		list2.add(new Person()); //编译通过
		list2.add(new Student()); //编译通过
	}

自定义泛型的测试

User类 

public class User {

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (age != other.age)
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public User() {
		
	}
	private int id;
	public User(int id, int age, String name) {
		super();
		this.id = id;
		this.age = age;
		this.name = name;
	}
	private int age;
	private String name;
}

 DAO类

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 定义泛型类DAO<T>
 * 创建一下方法
 * public void save(String id ,T entity):保存T类型对象到Map变量中
 * public T get(String id):从map中获取id对应的对象
 * public void update(String id,T entity):替换map中key为id的内容,改为entity对象
 * public List<T> list():返回map中存放的所有T对象
 * public void delete (String id):删除指定id对象
 * 
 * @author CharlieLiang
 * @param <T>
 *
 */
public class DAO<T> {

	private Map<String,T> map;
	
	public DAO() {
		map=new HashMap<>();
	}
	
	//保存T类型对象到Map变量中
	public void save(String id ,T entity) {
		map.put(id, entity);
	}
	
	//从map中获取id对应的对象
	public T get(String id) {
		return map.get(id);
	}
	
	//替换map中key为id的内容,改为entity对象
	public void update(String id,T entity) {
		if(map.containsKey(id)) {
			map.put(id, entity);
		}
	}
	
	//返回map中存放的所有T对象
	public List<T> list(){
		//错误的
//		Collection<T> values = map.values();
//		return (List<T>) values;
		//正确的
		List<T> list=new ArrayList<>();
		Collection<T> values = map.values();
		for(T t:values) {
			list.add(t);
		}
		return list;
	}
	
	//删除指定id对象
	public void delete (String id) {
		map.remove(id);
	}
}

DAOTest

import java.util.List;

import org.junit.jupiter.api.Test;

public class DAOTest {

	@Test
	public void testList() {
		DAO<User> dao = new DAO<>();
		dao.save("1001", new User(1001,34,"周杰伦"));
		dao.save("1002", new User(1002,20,"昆凌"));
		dao.save("1003", new User(1002,20,"蔡依林"));
		
		List<User> list = dao .list();
		list.forEach( i->System.out.println(i));
		
	}
	
	@Test
	public void testUpdate() {
		DAO<User> dao = new DAO<>();
		dao.save("1001", new User(1001,34,"周杰伦"));
		dao.save("1002", new User(1002,20,"昆凌"));
		dao.save("1003", new User(1002,20,"蔡依林"));
		
		dao.update("1003", new User(1003,40,"方文山"));
		
		List<User> list=dao.list();
		list.forEach(i->System.out.println(i));
	}
	
	@Test
	public void testDelete() {
		DAO<User> dao = new DAO<>();
		dao.save("1001", new User(1001,34,"周杰伦"));
		dao.save("1002", new User(1002,20,"昆凌"));
		dao.save("1003", new User(1002,20,"蔡依林"));
		
		dao.delete("1003");
		
		List<User> list=dao.list();
		list.forEach(i->System.out.println(i));
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux学习记录——칠 git、gdb部分基础知识以及进度条小程序

文章目录一、/r/n二、简单理解缓冲区概念三、进度条四、了解git五、初步学会使用gdb1、背景知识2、部分简单指令一、/r/n 在写小程序之前&#xff0c;我们先看一下/r和/n的区别。 /n我们遇到过&#xff0c;它叫做换行符。/r并不知道是什么符号。实际应用中&#xff0c;/n可以起…

鲍春健:从“走进客户”奔向“成为客户”

站在当下来看&#xff0c;小鹅通的服务力的特殊性在于其可以穿透三层&#xff0c;即以自身的服务力赋能客户的服务力。其中&#xff0c;一层是客户&#xff1b;一层是客户的服务&#xff1b;一层是客户的客户。 作者|斗斗 出品|产业家 累计终端用户数达8.2亿、最高日活14…

mysql系列之索引(待续)

目录一、索引简述1、什么叫索引2、索引的优缺点3、索引的使用场景二、索引的算法1、线性查找 Linear Search2、二分查找 Binary Search3、二叉查找树 Binary Search Tree4、平衡二叉树 AVL Tree5、B树6、B树三、B树和B树的理解1、B树和B树的区别2、数据库为什么使用B树而不是B树…

第二章.线性回归以及非线性回归—一元线性回归,代价函数,相关系数,决定系数

第二章.线性回归以及非线性回归 2.1 一元线性回归 1.概念&#xff1a; 1).自变量&#xff1a; 被用来进行预测的变量&#xff0c;相当于输入 2).因变量&#xff1a; 被预测的变量&#xff0c;相当于输出 3).回归分析&#xff1a; 用来建立方程模拟两个或者多个变量之间如何关…

从零开始学习Maven

maven Maven是apache公司开发的基于项目对象模型&#xff08;POM&#xff09; 可以通过一些描述信息来管理项目的构建、报告和文档的软件管理工具。 Maven 是用来管理项目&#xff0c;进行项目构建的一个软件。 java编写 项目构建流程&#xff1a; 1. 导入jar包 2. 配置文…

【MyBatis】RC隔离级别下,MyBatis 一级缓存、二级缓存造成的不一致情况

前言 数据库的MVCC 及 锁机制保证了数据的隔离、一致性。而建立在数据库之上的缓存&#xff0c;都会破坏掉数据库的一致性保障。本文探索在RC隔离级别下&#xff0c;MyBatis 一级缓存、二级缓存造成的坑。顺便复习一下 Spock 的用法&#xff0c;更加体验到了 Groovy 清爽的语法…

insert唯一索引加锁流程

MySQL版本&#xff1a;8.0.29 测试表&#xff1a; 测试数据&#xff1a; 开始测试&#xff1a; 事务1执行 加锁分析&#xff1a; mysql> SELECT * FROM performance_schema.data_locks\G *************************** 1. row ***************************ENGINE: INNO…

Express 中使用JWT进行登录验证

cookie 篇 : Node.js 中 cookie的验证登录 | session 篇 : Node.js 中 session验证登录 在前面讲过了两种验证登录的方式&#xff0c;其一是cookie&#xff0c;其二是session&#xff1b;那么在讲JWT之前先来简单的回顾这两种方式区别&#xff1b;cookie和sessi…

Java笔记023-包装类、String类、字符串的特性、String类、StringBuffer类、StringBuilder类

常用类包装类包装类的分类1、针对八种基本定义相应的引用类型-包装类2、有了类的特点&#xff0c;就可以调用类中的方法基本数据类型包装类booleanBooleancharCharacterbyteByteshortShortintIntegerlongLongfloatFloatdoubleDouble包装类和基本数据的转换演示包装类和基本数据…

LInux目录结构

文章目录Linux的目录结构Linux的目录结构Linux路径的描述方式目录各功能介绍HOME目录和工作目录Linux的目录结构 Linux的目录结构 Linux的目录结构是一个树型结构。 Windows 系统可以拥有多个盘符, 如 C盘、D盘、E盘 Linux没有盘符这个概念, 只有一个根目录 /, 所有文件都在…

【UE4 第一人称射击游戏】37-拾取副武器“M4A1”

上一篇&#xff1a;【UE4 第一人称射击游戏】36-切换武器时改变UI本篇效果&#xff1a;在拾取副武器“M4A1”前&#xff0c;点击键盘2键是无法切换武器的&#xff0c;当拾取武器后&#xff0c;点击键盘2键可以切换武器&#xff08;目前仅是右下角的图标和文字实现了切换&#x…

VBA小模板,一个不放回的抽奖用的例子

1 问题 一个不放回的抽奖用VBA怎么写&#xff0c;下面用一个类似对对碰/ 翻牌子的游戏&#xff08;抽到的奖励不放回&#xff0c;可抽的东西越来越少&#xff09;来举例说明 1.1 首先要回顾下几个经典的随机模型 古典概型&#xff0c;重点就是每次抽奖的各个奖品&#xff0c;概…

宇视门禁一体机接线图

宇视门禁一体机接线图宇视门禁一体机带反馈信号电磁锁接线图门禁的GND线通用&#xff0c;可以连到同一根线上&#xff0c;也可以分开连简单整理如图一体机线颜色和功能对应表颜色线路绿色RS485_A粉色RS485_B黑色GND蓝色WIEGAND_OUT_D0白色WIEGAND_OUT_D1灰色WIEGAND_IN_D0棕色W…

测试面试真题|工作2年,从小厂到大厂,薪资翻倍是怎样的体验?

最近&#xff0c;霍格沃兹测试学院学员 C 同学成功拿下某互联网大厂年薪 30W 测试开发岗位 Offer&#xff0c;顺利完成从手工测试工程师到测试开发的逆袭&#xff0c;薪资翻倍&#xff08;涨幅 100%&#xff09;&#xff0c;并获得了学院颁发的优秀学员奖学金。C 同学工作刚满 …

【3D目标检测】Delving into Localization Errors for Monocular 3D Object Detection

目录概述细节错误分析概述 本文是基于单目图像的3D目标检测方法。 【2021】【MonoDLE】 研究的问题: 核心问题&#xff1a;如何提高基于单目图像的3D目标检测的效果。作者量化了每个子任务的整体影响&#xff0c;观察到以下现象 观察一&#xff1a;定位误差是制约目标检测性…

变异凯撒题解

题目变异凯撒&#xff0c;说明没有使用一般的凯撒加密看到一个密码&#xff0c;我们可以找一下规律首先密文不完全是字母&#xff0c;但是经典凯撒加密的密文一定都是字母&#xff0c;说明这个题目可能是ASCLL码表偏移&#xff0c;而不是字母表偏移经典凯撒加密是字母和字母的偏…

SSM纯注解后台代码整合(Spring+SpringMvc+Mybatis)

SSM后台整合&#xff08;SpringSpringMvcMybtis事务Rest风格统一结果封装统一异常处理拦截器&#xff09; 文章目录1 基础环境搭建1.1 建表1.2 创建web项目1.3 导入依赖坐标&#xff08;pom.xml&#xff09;1.4 包路径的创建1.5 在pojo包下编写book实体类1.6 在webapp包下导入静…

很多人还不知道中视频计划手机上发布多端横竖屏视频的方法

如果说你刚开始接触中视频&#xff0c;你必须要学会的小知识。 横屏视频是16&#xff1b;9的视频&#xff0c;一般是手机横向拍摄的视频。 上传这样的视频有两种方法。第一种是需要用到电脑&#xff0c;第二种就是我今天要分享的这种&#xff0c;没有电脑&#xff0c;我们用手…

测试新人入职第一天都做什么?

测试入职第一天都做什么&#xff1f; 大家都知道&#xff0c;入职一家新公司就是一个新的起点&#xff0c;新的开始。不管在之前公司干了多久&#xff0c;还是第一次踏入社会进入企业上班&#xff0c;都需要遵守新公司的规则以及规章制度。不管企业的规章制度是什么&#xff0…

前端提交信息规范 commit规范 commitlint husky commitizen

前端提交规范 约定式提交约定式提交安装commitizen 及其适配器husky commitlint 提交校验至此恭喜你已经配置好提交校验了&#xff0c;快去试试吧技术同学开发中有没有出现 &#xff1a; 因某种原因当需要回滚&#xff0c;这时候一看之前提交的massage真的乌烟瘴气 无法分辨回…