Java 泛型方法/接口、泛型限定

article/2025/10/15 20:17:07
 文章目录一、为什么要定义泛型方法1、从泛型类到泛型方法的演变过程2、定义泛型方法的好处二、创建一个泛型方法格式常用的形式三、泛型接口1、格式2、例子四、类型通配符(泛型的高级应用)1、什么是通配符 (?)2、类型通配符上限定(? extends T =>可以接收T类型或者T的子类型)3、类型通配符下限定 (? super T => 可以接收T类型或者T父类型)

一、为什么要定义泛型方法

1、从泛型类到泛型方法的演变过程
我们先来看个例子

//定义一个泛型类,并定义如下两个方法
class Test<T>
{public  void show(T t){System.out.println(t);}public void print(T t){System.out.println(t);}	/*  以前是这样定义,现在一个方法搞定public void show(String t){	}public void show(Integer t){	}或者public void show(Object obj){	}*/
}//在manin方法代码如下public static void main(String[] args) {Test<String> d = new Test<String>();d.show("java");d.print("Object-C");Test<Integer> e = new Test<Integer>();e.show(2);e.print(new Integer(5));	}

上面是一个简单的代码demo,运行没问题,正常输出。但是你会发现,其实代码有点冗余。我们定义了一个泛型类,并定义了 show(T t)print(T t)方法。发现: 泛型类定义的泛型,在整个类中有效如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所要操作的类型已经固定了。就像上面main方法中。对象d,只能操作String类型,如果你要操作其他类型,只能额外去创建其他泛型对象e

设想下,如果我能把泛型定义在方法上,这样不就可以优雅解决问题。于是变化代码如下

//定义一个类,并定义如下两个泛型方法
class Test
{public <T>  void show(T t){System.out.println(t);}public <T> void print(T t){System.out.println(t);}	public <U,T> void sum(U u,T t){System.out.println(u+" version is "+t);}
}
// main方法如下
public static void main(String[] args) {Test d = new Test();d.show("java");d.print(5);d.sum("java", new Double(8));}

Test不再是泛型类,泛型方法show(T t)print(T t)sum(U u,T t) 更具有扩展性。

2、定义泛型方法的好处

泛型方法可以让不同方法操作不同类型,且类型还不确定。
与泛型类不同,泛型方法的类型参数只能在它锁修饰的泛型方法中使用。

二、创建一个泛型方法格式

1、常用的形式

访问修饰符 [static][final] <类型参数列表> 返回值类型 方法名([形式参数列表])

备注:[] 代可有可无的意思,泛型方法可以是实例方法或静态方法,类型参数可以在静态方法中,这是与泛型类最大的区别

三、泛型接口

1、格式

interface 接口名<类型参数表>

2、例子

定义一个泛型接口

interface showInterface<T>
{public void show(T t);}

(1) 实现类确定了类型

class ShowClass implements showInterface<String>{public void show(String t){System.out.println("show:"+t);}
}

(2) 实现类类型不确定

class ShowClass<T> implements showInterface<T>{public void show(T t){System.out.println("show:"+t);}
}

main方法

	public static void main(String[] args) {ShowClass<Integer> obj = new ShowClass<Integer>();obj.show(6);/*ShowClass obj = new ShowClass();obj.show("java");*/}

四、类型通配符(泛型的高级应用)

1、什么是通配符 (?)
看个例子就明白了。定义两个集合,分别输出两个集合的元素。

	public static void main(String[] args) {ArrayList<String> a1 = new ArrayList<String>();a1.add("a");a1.add("b");a1.add("c");ArrayList<Integer> a2 = new ArrayList<Integer>();a2.add(1);a2.add(2);a2.add(3);}

在我们没学习泛型之前,我们会封装静态方法如下:

	public static void printList(ArrayList list){for (Iterator iterator = list.iterator(); iterator.hasNext();) {Object object = (Object) iterator.next();System.out.println(object);	}}

代码买啥毛病,运行也正确。会有一个疑问。为什么参数没定义泛型,但是却可以接受泛型呢?泛型是jdk1.5出来的,老版本肯定要兼容新版本。

在我们学习泛型方法后,我们进一步将代码修改如下:

	public static <T>void vistor(ArrayList<T> a){Iterator<T> iterator = a.iterator();while(iterator.hasNext()){T t = iterator.next(); System.out.println(t);}}

定义一个泛型方法。如果是泛型类,是不允许泛型定义在static上面的

如果不想定义泛型方法,又能够解决问题呢?这就要用到一个通配符的玩意

	//占位符,也称为通配符。表示元素类型可以匹配任意类型public static void sop(ArrayList<?> a){for(Iterator<?> it = a.iterator();it.hasNext();){System.out.println(it.next());}}

泛型方法T如果是具体类型的话,可以接收T t = iterator.next();。?是占位符,不明确具体类型,无法接收。

这种带通配符ArrayList<?> aList 仅仅表示他是各种泛型的父类,并不能把元素添加到其中。

我做了奇怪的例子

 ArrayList<?> list = new ArrayList<String>();
list.add(null);

上面说,带通配符ArrayList<?> aList 仅仅表示他是各种泛型的父类,并不能把元素添加到其中。是不是想违背了?仔细想想,null是任意引用类型的实例。这比较特殊。

2、类型通配符上限定(? extends T)

同样看一个例子. 定义一个集合,遍历元素的方法并输出。

//定义一个Person类
class Person
{private String name;public Person(String name){this.name = name;}public String getNmae(){return this.name;}
}
// 定义一个Student 并继承 Person
class Student extends Person
{Student(String name){super(name);}
}main方法如下
public static void main(String[] args) {ArrayList<Person> a1 = new ArrayList<Person>();a1.add(new Person("abc1"));a1.add(new Person("abc2"));a1.add(new Person("abc3"));printMethod(a1);// 下面是错误的。a2存的是Person,存在继承的话,也能放worker。但是等号右边只能存Student,存不进worker.类型安全问题。左右两边要一致ArrayList<Student> a2 = new ArrayList<Student>();a2.add(new Student("abc--1"));a2.add(new Student("abc--2"));a2.add(new Student("abc--3"));printMethod(a2); // ArrayList<Person> a2 = new ArrayList<Student>();//如果我想调用也printMethod(a2);没毛病。怎么做?。 第一想法直接给占位符。但是带来一问题,不能调用具体方法。}// 与main方法同级的静态工具类方法public static void printMethod(ArrayList< Person> a1){Iterator<Person> it = a1.iterator();while(it.hasNext()){System.out.println(it.next().getNmae());}}

如果我想调用也printMethod(a2);没毛病。怎么做?。 第一想法直接给占位符。但是带来一问题,不能调用具体方法。泛型也是一样的。如果我们想两者兼得,既能打印Stuednt,也能打印 Person,我们将printMethod修改如下

	public static void printMethod(ArrayList<? extends Person> a1){Iterator<? extends Person> it = a1.iterator();while(it.hasNext()){System.out.println(it.next().getNmae());}}

我们称? extends T 为 泛型上限定: 可以接收T和T的子类

3、类型通配符下限定<? super T>

接收T类型或者T的父类型
在这里插入图片描述
从集合TreeSet的构造方法我们可以看到 下限定的运用。我们也可以集合实际例子。

TreeSet<Person> ts = new TreeSet<Person>();  //Comparator<? super E> comparator
ts.add(new Person("d"));
ts.add(new Person("f"));
ts.add(new Person("g"));	

比较器如下

// 这边的T写Student和Person都是可以的
class comp implements Comparator<Person>
{public int compare(Person s1,Person s2){return s1.getNmae().compareTo(s2.getNmae());}
}

其实限定的目的是为了扩展指定类型。

通过上面比较器参数和我们实现的比较器。如果我们比较器的泛型为 Student,那么只能比较Student。当未来某一天,Person有新子类出现的话,那么该比较器就不适用了。所以Java 的API 的考虑扩展性的同时,已经设置了泛型下限定,你可以传T类型或者T的父类型。

在这里插入图片描述


http://chatgpt.dhexx.cn/article/lZim724g.shtml

相关文章

Java 泛型方法

本文包含&#xff1a; 定义泛型方法泛型方法和类型通配符的区别Java 7 的“菱形”语法与泛型构造器设定通配符下限泛型方法与方法重载Java 8 改进的类型推断 1. 定义泛型方法 假设需要实现这样一个方法&#xff1a;该方法负责将一个 Object 数组的所有元素添加到一个 Collec…

【java】泛型方法的定义

一、定义泛型方法的格式 二、调用泛型方法的语法格式 三、解释 1、定义泛型方法时&#xff0c;必须在返回值前边加一个<T>&#xff0c;来声明这是一个泛型方法&#xff0c;持有一个泛型T&#xff0c;然后才可以用泛型T作为方法的返回值。 2、Class<T>的作用就是指…

Java 中的泛型(两万字超全详解)

文章目录 前言一、泛型概述1. 什么是泛型&#xff1f;为什么要使用泛型&#xff1f;2. 泛型使用场景3. 泛型概述小结 二、泛型类1. 泛型类的定义2. 泛型类的使用 三、泛型接口四、泛型方法1. 泛型方法的定义2. 泛型方法的使用3. 泛型方法中的类型推断 五、类型擦除1. 什么是类型…

Java中的泛型方法

泛型是什么意思在这就不多说了&#xff0c;而Java中泛型类的定义也比较简单&#xff0c;例如&#xff1a;public class Test{}。这样就定义了一个泛型类Test&#xff0c;在实例化该类时&#xff0c;必须指明泛型T的具体类型&#xff0c;例如&#xff1a;Test t new Test();&am…

【软件测试】使用C++ Test进行动态测试

测试目的 1.掌握动态测试的方法。 2.掌握使用Parasoft C Test进行动态测试。 测试环境 Windows XP, Parasoft C Test 9.2 测试内容 使用Parasoft C Test进行动态测试&#xff0c;包括自动化测试、自定义测试用例、数据源测试用例、桩函数机制。 测试过程及结果 4.1 基于…

测试基础-动态白盒测试

1.动态白盒测试 定义&#xff1a;也称结构化测试。利用查看代码功能&#xff08;作什么&#xff09;和实现方式&#xff08;怎么做&#xff09;得到的信息来确定哪些需要测试、哪些不需要测试、如何开展测试。 动态白盒测试包括以下4个部分&#xff1a; 直接测试底层函数、过…

符合功能安全要求的动态测试工具-TESSY

Tessy是一个专门针对嵌入式软件的C/C代码进行单元、集成测试的工具&#xff0c;它可以自动化地执行测试、评估测试结果并生成测试报告。 Tessy的目标就是&#xff1a;通过自动化整个测试周期&#xff0c;支持针对C语言的单元测试/集成测试&#xff0c;同时&#xff0c;Tessy也…

软件测试复习03:动态测试——白盒测试

作者&#xff1a;非妃是公主 专栏&#xff1a;《软件测试》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 逻辑覆盖法&#xff1a;最常用程序插桩技术基本路径法点覆盖边覆盖边对覆盖主路径覆盖 符号测试错…

动态测试

动态测试 1.1 动态分析技术 虽然静态分析技术不需要软件的执行&#xff0c;而从动态分析本身来看更像是一个“测试”。它包含了系统的执行。当软件系统在模拟的或真实的环境中执行之前、之中和之后&#xff0c;对软件系统行为的分析是动态分析的主要特点。动态分析包含了程序在…

软件测试复习04:动态测试——黑盒测试

作者&#xff1a;非妃是公主 专栏&#xff1a;《软件测试》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 等价划分法边值分析法错误推测法因果图法示例 习题 等价划分法 等价类&#xff1a;一个几何&…

动态测试方法

动态测试方法&#xff0c;通过实际执行代码去发现潜在代码错误的测试方法。 人工动态方法 人工动态方法&#xff0c;可以真正检测代码的业务逻辑功能&#xff0c;其关注点是“什么样的输入&#xff0c;执行了什么代码&#xff0c;产生了什么样的输出”&#xff0c;主要用于发…

linux同步时间服务器时间配置

linux时间同步简单配置如下(centos7.x)&#xff1a; 安装时间服务器(系统一般会自带)&#xff1a; yum install ntp ntpdate -y 时间服务器临时配置(重启该配置失效)&#xff1a; ntpdate 192.133.203.89(时间服务器ip) 时间服务器配置: vim /etc/chrony.conf 进入vim编辑页面…

linux 多台机器修改时间同步

修改东八区 首先第一步&#xff0c;通过命令 &#xff1a;date -R 查看当前系统所在时区。如是0800&#xff0c;则是东八区&#xff0c;也就是我们当下的北京时间&#xff0c;如不是&#xff08;如下图&#xff09;&#xff0c;做如下调整。 命令行键入命令&#xff1a;tzsele…

Linux时间同步:chrony

linux7以上版本都自带chrony服务 如果没有安装&#xff0c;则使用yum安装&#xff0c;如果安装了&#xff0c;请忽略 yum -y install chrony 说明&#xff1a;Chrony由两个程序组成&#xff0c;分别是chronyd和chronyc chronyd是一个后台运行的守护进程&#xff0c;用于调整…

linux同步时间(通过定时任务,按时同步时间)

安装同步器 yum install -y ntpdate同步时间(一次性同步,挂起或关闭虚拟机后时间再次不同步) ntpdate 0.centos.pool.ntp.org制作定时任务,同步时间 安装定时任务 yum –y install crontabs制作一个定时任务,设置开机自启 systemctl enable crond --now配置定时任务文件,添…

Linux同步时间的方法

方法一&#xff1a;非生产时使用 第一种是在所有机器上&#xff0c;使用连接工具的并发命令功能&#xff0c;同时运行修改时间命令&#xff0c;比如执行date -s “2019-05-25 17:00:00” &#xff0c;这个方法适合自己测试环境用 第二种就是安装了一个ntpdate命令&#xff0c…

word中插入visio流程图的操作

1、首先需要将画好的流程图进行保存&#xff0c;注意保存的格式是vsdx 2、新建个word文档&#xff0c;找到插入-对象&#xff0c;打开如下&#xff1a; 3、点击由文件创建-浏览中找到你想插入的对应的visio的文件 4、找到之后&#xff0c;下一步就是直接点击确定&#xff0c;…

Visio如何裁剪图片

参考 Visio如何裁剪图片 - 云社区 - 腾讯云 1、首先点击打开Visio软件&#xff0c;如图所示 2、接着在Visio中装载需要处理的图片&#xff0c;点击文件-打开&#xff0c;如图所示 3、加载图片后&#xff0c;点击选中图片&#xff0c;如图所示 4、此时Visio上方菜单栏&#xf…

visio2019怎么对图片加箭头标注,Visio设置图片作为背景

visio2019怎么对图片加箭头标注&#xff0c;Visio设置图片作为背景 单个图片总时作为一个对象被标注&#xff0c;没办法标注细节&#xff0c;可以将图片作为背景&#xff0c;进行标注 首先&#xff0c;插入&#xff0c;新建页&#xff0c;背景页&#xff0c;把欲编辑的图片放…