【java学习—十一】泛型(1)

news2025/7/19 21:07:44

文章目录

  • 1. 为什么要有泛型Generic
  • 2. 泛型怎么用
    • 2.1. 泛型类
    • 2.2. 泛型接口
    • 2.3. 泛型方法
  • 3. 泛型通配符
    • 3.1. 通配符
    • 3.2. 有限制的通配符


1. 为什么要有泛型Generic

在这里插入图片描述

    泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
    Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		List list = new ArrayList<>();
		
		//不指定泛型,可以向list集合中添加各种类型元素
		list.add(111);
		list.add("sss");
		list.add(true);
		
		//需求,只能在集合中存字符串
		List<String> l = new ArrayList<String>();
		
		l.add("xx");
//		l.add(111);//指定的String类型,不可以添加String以外的元素类型
		
		
	}

}

    Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段
    解释:
    视频中老师说:比如上段代码中最后一行的l.add(111)在编译期间就会报错,只有删除这一行,或者将里面的数据改成String类型后,才可以通过编译。

2. 泛型怎么用

2.1. 泛型类

对象实例化时不指定泛型,默认为: Object 。
泛型不同的引用不能相互赋值。

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {

		A<String> a1 = new A<String>();//在new A的对象的时候,指定泛型的类型String
		a1.setKey("xxxx");//对象使用setKey(T key)方法,中的key形参就是String
		System.out.println(a1.getKey());//T getKey(),返回值就有new对象确定返回值是String
		
		A<Integer> a2 = new A<Integer>();
		a2.setKey(1);
		Integer i = a2.getKey();
		
		A a3 = new A();//不指定泛型,相当于指定了一个Object类型
		//A<Object> a3 = new A<Object>();//等同于上行代码
		a3.setKey(new Object());
		Object obj = a3.getKey();
		
		//同样的类,但是在new对象时指定不同的数据类型,那么这些对象不能互相赋值
		a1 = a2;//错误,不同的数据类型不能互相赋值
		
		
	}

}

/**
 * 此处的泛型‘T’可以任意的取名,即可换成A,B,C等
 * 一般使用T,译为type
 * @author 14532
 *
 * @param <T>
 */
class A<T>{//< >中的内容可以任何取名,按惯例是T
	private T key;
	public void setKey(T key) {
		this.key = key;
	}
	
	public T getKey() {
		return this.key;
	}
}

2.2. 泛型接口

定义一个泛型接口:

interface Generator<T> {
    T next();
}

①未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
②如果实现接口时,指定接口的泛型的具体数据类型,这个类实现接口所有方法的位置都要替换实际的具体数据类型

举例:

package day11;

public class Test1 {
	public static void main(String[] args) {
		B1<Object> b1 = new B1<Object>();
		B1<String> b11 = new B1<String>();
		
		B2 b2 = new B2();//不用指定泛型,指定泛型反而会报错
	}
}

interface IB<T>{
	T test(T t);
}


/**
 * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
 * @author 14532
 *
 * @param <T>
 */
class B1<T> implements IB<T>{//B1<T>:未传入实参,将泛型的声明<T>也一起加到类中
	
	@Override
	public T test(T t) {
		return t;
	}
}


/**
 * 如果实现接口时指定接口的泛型的具体数据类型
 * 这个类实现接口所有方法的位置都要替换实际的具体数据类型
 * @author 14532
 *
 */
class B2 implements IB<String>{
	
	@Override
	public String test(String t) {
		return null;
	}
}

2.3. 泛型方法

    方法,也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

泛型方法的格式:

public class DAO {
    public <E> void show(E e){
        System.out.println(e.toString());
    }
    public <T> T show1(T t){
        return t;
    }
}

举例:



class Cc{
	
    /**
     * 无返回值的泛型方法
     * @param <T>
     * @param s
     */
	public <T> void test(T s) {
		T t = s;
	}
	
	/**
	 * 有返回值的泛型方法
	 * @param <T>
	 * @param s
	 * @return
	 */
	public <T> T test1(T s) {
		return s;
	}
	
	
	/**
	 * 形参为可变参数的泛型方法
	 * @param <T>
	 * @param strs
	 */
	public <T> void test2(T... strs) {
		for(T s : strs) {
			System.out.println(s);
		}
	}
	
}

举例2:

package day11;

public class Test1 {
	public static void main(String[] args) {

		Cc<Object> c = new Cc<Object>();
		c.test("xxx");
		//泛型方法在调用之前没有固定的数据类型
		//在调用时,传入的参数是什么类型,就会把泛型改成什么类型
		//也就是说,泛型方法会在调用时确定泛型的具体数据类型
		Integer i = c.test1(2);//传递的参数是Integer,泛型就固定成Integer,返回值就是Integer
		Boolean b = c.test1(true);//传递的参数是Boolean,泛型就固定成Boolean,返回值就是Boolean
		
	}
}





class Cc<E>{
	private E e;
	
//	public static void test3() {
//		//在静态方法中不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
//		//System.out.println(this.e);
//	}
	/**
	 * 静态方法的泛型方法
	 * @param <T>
	 * @param t
	 */
	public static <T> void test3(T t) {
		//在静态方法中不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
		System.out.println(t);
	}
    /**
     * 无返回值的泛型方法
     * @param <T>
     * @param s
     */
	public <T> void test(T s) {
		//在类上定义的泛型,可以在普通的方法中使用
		System.out.println(this.e);
		T t = s;
	}
	
	/**
	 * 有返回值的泛型方法
	 * @param <T>
	 * @param s
	 * @return
	 */
	public <T> T test1(T s) {
		return s;
	}
	
	
	/**
	 * 形参为可变参数的泛型方法
	 * @param <T>
	 * @param strs
	 */
	public <T> void test2(T... strs) {
		for(T s : strs) {
			System.out.println(s);
		}
	}
	
}

3. 泛型通配符

3.1. 通配符

不确定集合中的元素具体的数据类型,使用"?"表示所有类型
如:

	public void test(List<?> list){
		System.out.println(list);
	}

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test2 {
	public static void main(String[] args) {
		Dd d = new Dd();
		List<String> l1 = new ArrayList<String>();//?:可以代表各种类型,如String、Integer
		d.test(l1);
		
		List<Integer> l2 = new ArrayList<Integer>();
		d.test(l2);
	}

}

class Dd {
	public void test(List<?> list) {//test方法需要一个list集合的参数,不确定list集合中到底是存的数据的类型是什么
		
	}
}

3.2. 有限制的通配符

举例:

<? extends Person> (无穷小, Person)
只允许泛型为Person及Person父类的引用调用

<? super Person> [Person, 无穷大]
只允许泛型为Person及Person父类的引用调用

<? extends Comparable>
只允许泛型为实现Comparable接口的实现类的引用调用

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test2 {
	public static void main(String[] args) {
		Dd d = new Dd();
		
		//list参数的元素数据类型是CC1及其子类
		List<CC1> lc = new ArrayList<CC1>();
		d.test1(lc);
		
		List<DD1> ld = new ArrayList<DD1>();
		d.test1(ld);
		
//		List<BB1> lb = new ArrayList<BB1>(); //BB1不是CC1的子类
//		d.test1(lb);
		
		
		//list参数的元素数据类型是CC1及其父类 
		d.test2(lc);
		
		List<BB1> lb = new ArrayList<BB1>();
		d.test2(lb);
		
		List<AA1> la = new ArrayList<AA1>();
		d.test2(la);
		
//		d.test2(ld);//DD1不是CC1的父类
		
		//list参数的元素数据类型是IA的实现类
		List<IAImpl> lia = new ArrayList<IAImpl>();
		d.test3(lia);
		
//		d.test3(la);//AA1不是IA的实现类

	}
}

class Dd {
	public void test(List<?> list) {//test方法需要一个list集合的参数,不确定list集合中到底是存的数据的类型是什么
		
	}
	
	public void test1(List<? extends CC1> list) {//list参数的元素数据类型是CC1及其子类
		
	}
	
	public void test2(List<? super CC1> lsit) {//参数的元素数据类型是CC1及其父类 
		
	}
	
	public void test3(List<? extends IA> lsit) {//list参数的元素数据类型是IA的实现类
		
	}
}


class AA1{}

class BB1 extends AA1{}

class CC1 extends BB1{}

class DD1 extends CC1{}

interface IA{}

class IAImpl implements IA{}

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

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

相关文章

精选10款Python可视化工具,请查收

今天我们会介绍一下10个适用于多个学科的Python数据可视化库&#xff0c;其中有名气很大的也有鲜为人知的。 1、matplotlib matplotlib 是Python可视化程序库的泰斗。经过十几年它仍然是Python使用者最常用的画图库。它的设计和在1980年代被设计的商业化程序语言MATLAB非常接近…

的修工单管理系统好用吗?工单系统应该怎么选?

在当今的数字化时代&#xff0c;企业运营效率的高低往往取决于其内部管理工具的先进性和实用性。工单管理系统作为企业运营中的重要工具&#xff0c;其作用日益凸显。市场上存在许多工单管理系统&#xff0c;但“的修”以其独特的产品差异化和优势&#xff0c;在竞争中独树一帜…

Linux C语言进阶-D3~D4字符串处理函数

求字符串长度函数strlen、字符串拷贝strcpy、字符串连接strcat、字符串比较strcmp 头文件<string.h> 求字符串长度strlen函数 1、计算字符串长度&#xff0c;并且遇到\0结束&#xff0c;返回字符串长度 2、 计算字符串长度&#xff0c;遇到转义字符&#xff0c;\不算在内…

基于ASP.NET MVC + Bootstrap的仓库管理系统

基于ASP.NET MVC Bootstrap的仓库管理系统。源码亲测可用&#xff0c;含有简单的说明文档。 适合单仓库&#xff0c;基本的仓库入库管理&#xff0c;出库管理&#xff0c;盘点&#xff0c;报损&#xff0c;移库&#xff0c;库位等管理&#xff0c;有着可视化图表。 系统采用Bo…

消息的订阅与发布机制

消息的订阅与发布机制 功能&#xff1a;可完成任意组件之间数据的传递&#xff08;同全局事件总线功能一样&#xff09;区别&#xff1a;与全局事件总线相比&#xff0c;消息的订阅和发布机制需要使用第三方库。我用的是pubsub-js库&#xff0c;其他的第三方库也可以使用&#…

如何在崩坏3rd游戏中使用万安单机单窗口软件进行游戏道具收购?

如何在崩坏3rd游戏中使用窗口软件进行游戏道具收购&#xff1f; 首先&#xff0c;定义在崩坏3rd游戏中&#xff0c;使用窗口软件进行游戏道具收购涉及到账户绑定、软件下载、游戏内购买等步骤。 我在玩崩坏3rd游戏时&#xff0c;使用了窗口软件成功完成了游戏道具的收购。 步骤…

【产品体验】OA办公系统

一、演示地址 http://admin.dianshixinxi.com:90/index 二、办公管理功能 1.我的待办&#xff1a;当前登录用户&#xff0c;办理任务 2.通知公告&#xff1a;通知与公告&#xff0c;已发布通知公告会显示在首页 3.自定义表单&#xff1a;自定义表单&#xff0c;托拉拽的形式…

【Python 零基础入门】Numpy 常用函数

【Python 零基础入门】内容补充 3 Numpy 常用函数 概述Numpy 数组创建np.arangenp.linspace 数组操作reshapeflattenconcatenatesplitvstackhstack 数学运算add 相加subtract 相减multiply 相乘divide 相除 通用函数np.sqrt 平方根np.log 对数np.exp 指数np.sin 正弦 概述 Num…

WPS文件恢复怎么做?记得掌握这5个方法!

“我保存在WPS里的部分文件丢失了&#xff0c;大家快帮我想想办法吧&#xff0c;有什么方法可以恢复这些WPS里的文件吗&#xff1f;真的很重要&#xff01;” WPS Office是一款流行的办公套件&#xff0c;给用户在办公和学习方面提供了很多的便利。但在整理文件时&#xff0c;我…

CV计算机视觉每日开源代码Paper with code速览-2023.10.30

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【语义分割】&#xff08;NeurIPS2023&#xff09;SmooSe…

pc通过window.open打开新页面,新页面要使用原来页面的token

原文链接&#xff1a; https://blog.csdn.net/weixin_42342065/article/details/127420783 (以下为本人笔记使用) 对于前端来说&#xff0c;一般在登录获取token之后会把token存入缓存以及放置在Request Headers请求头中&#xff0c;但是使用iframe/window.open/a这三种标签打…

高并发项目部署以及优化手段

文章目录 &#x1f50a;博主介绍&#x1f916;博主的简介&#x1f4e5;博主的目标 &#x1f964;本文内容&#x1f31f; 服务器配置&#x1f34a; 文件系统参数、TCP网络层参数等系统参数&#x1f34a; 修改文件描述符大小 &#x1f31f; SpringBoot的配置&#x1f34a; 1. 配置…

WPS Office 制作下拉两级联动

文章目录 前言WPS Office 制作下拉两级联动1. 准备两级联动数据![在这里插入图片描述](https://img-blog.csdnimg.cn/dc8c21c5f12349aeb467eed266888618.png)2. 设置一级下拉3. 设置二级联动下拉 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xf…

k8s资源对象--pod

创建pod: kubectl get pod cp test_pod_1.yaml nginx_pod.yaml cah 查看详细信息&#xff1a; pod的状态处于pending可能的原因&#xff1a;一个或多个没有运行 由于当前所有节点没有可用节点&#xff08;所有节点资源不足&#xff0c;所有节点&#xff09; 查看所有&…

全网最详细4W字Flink全面解析与实践(下)

本文已收录至GitHub&#xff0c;推荐阅读 &#x1f449; Java随想录 微信公众号&#xff1a;Java随想录 原创不易&#xff0c;注重版权。转载请注明原作者和原文链接 文章目录 Flink State状态CheckPoint & SavePointCheckPoint原理SavePoint原理 StateBackend状态后端Memo…

LiveGBS流媒体平台GB/T28181常见问题-国标级联海康国标级联大华国标级联华为等,配置了国标级联, 上级看不到通道该怎么办?

LiveGBS常见问题-国标级联海康国标级联大华国标级联华为等&#xff0c;配置了国标级联, 上级看不到通道该怎么办? 1、如何配置国标级联2、上级看不到通道排查2.1、是否共享通道2.3、通道编号是否满足上级要求 3、如何抓包分析4、搭建GB28181视频直播平台 1、如何配置国标级联 …

ASO优化之如何制作Google Play的长短描述

应用的描述以及标题和图标是元数据中最关键的元素&#xff0c;可以影响用户是否决定下载我们的应用程序。简短描述的长度限制为80个字符&#xff0c;它提供了更多的有关应用背景信息的机会。 1、简短描述帮助用户快速了解我们应用。 确保内容丰富的同时&#xff0c;保持简洁和…

Expected indentation of 16 spaces but found 8 spaces.eslintvue/script-indent

问题&#xff1a;Expected indentation of 16 spaces but found 8 spaces.eslintvue/script-indent 原因&#xff1a; 严格地检查缩进问题&#xff0c;并不是报错 解决&#xff1a; 方法一&#xff1a;我们可以关闭这个检查规则&#xff08;好像没用&#xff09; .eslintrc.js…

02-详细介绍Vue中的数据代理和数据响应式

数据代理 MVVM 原生的Javascript代码Model和View没有分离,如果数据发生任意的改动, 接下来我们需要编写大篇幅的JS代码操作DOM元素更新视图 MVVM是目前前端开发领域当中倡导Model和View进行分离的开发思想或者架构模式,大部分主流框架如Vue和React都借鉴了这个MVVM思想 Mod…

介绍几款Linux 下终极SSH客户端

安全外壳协议&#xff08;Secure Shell&#xff0c;简称 SSH&#xff09;是一种网络连接协议&#xff0c;允许您通过网络远程控制计算机。特别是在Linux命令行模式下&#xff0c;使用SSH&#xff0c;可以很方便管理linux上的运维工作。以下是一些最受欢迎的Linux SSH客户端&…