java中的泛型(二)——泛型接口以及泛型方法

        在上一篇文章中,简要地对泛型的概念以及泛型类的使用进行了说明。除了在泛型类之外,泛型还可以在接口和方法中使用。

泛型接口

        对于泛型接口,它的声明方式为: public interface 接口名 <泛型>{泛型定义的抽象方法}。这个声明方式和泛型类的声明方式基本一致。在定义了泛型接口后,在实现这个泛型接口的时候,要求我们指定泛型所代表的具体类型。比如在下面的这个演示代码中,定义了泛型抽象接口Igeneric,用泛型T来代表数据类型,因此在抽象方法中就可以使用泛型T来代表方法返回的的类型以及方法中需要传入的参数的类型。这里要注意泛型接口定义时的泛型与抽象泛型方法中使用的泛型的关系。

        在泛型接口Igeneric的实现接口IgenericIme中,我们给定了泛型T的具体类型为String,这时如果通过实现类IgenericIme来创建对象,那么创建的对象中的数据类型就是String类。在这里就必须说到实例化对象的不同方式——通过接口实例化对象以及通过实现类实例化对象。在通过泛型接口的的实现类来实例化对象的时候,它的实例化方式与普通类的实例化没有区别,比如在下面演示代码中的igenericIme。但是当我们用泛型接口来实例化对象的时候就要特别注意,这种实例化方式要指定泛型所代之的类型并且还要指定特定的实现类,它的语法格式为:泛型接口名称<泛型指代的类型> 对象名称 = new 泛型接口的实现类名称();。就像演示代码中的对象igeneric以及对象igeneric1一样,并且要注意,尖括号中的泛型指代的类型要和接口的实现类中的保持一致,如果将对象igeneric中的泛型指代的名称输入为Integer,那么因为和后面的实现类中的泛型不同,所以程序无法通过编译。

package com.generic.demo;/*** 泛型接口*/
public interface Igeneric<T> {abstract T getName(T name);
}
package com.generic.demo;/*** 泛型接口的实现类*/
public class IgenericIme implements Igeneric<String >{@Overridepublic String  getName(String name) {return name;}
}
package com.generic.demo;public class IgenericIme1 implements Igeneric<Integer>{@Overridepublic Integer getName(Integer name) {return name;}
}
package com.generic.demo;public class TestIgeneric {public static void main(String[] args) {//通过实现类实例化IgenericIme igenericIme = new IgenericIme();String name1 = igenericIme.getName("尚学堂");System.out.println(name1);//通过接口实例化Igeneric<String> igeneric = new IgenericIme();String name2 = igeneric.getName("123");System.out.println(name2);Igeneric<Integer> igeneric1 = new IgenericIme1();Integer name3 = igeneric1.getName(125);System.out.println(name3);}
}

泛型方法

        静态泛型方法与非静态泛型方法

        在之前说的泛型类以及泛型接口的部分能够发现,我们定义在类和接口上的泛型在它们的方法中仍然可以使用,但是有时我们需要的仅仅是在一个指定的方法上使用泛型而不需要在整个类和接口上使用泛型,因此泛型方法的概念就被提出了。泛型方法指的是将方法中的参数类型定义为泛型,以便在调用时接收不同的参数类型的现象。泛型方法可以分为非静态泛型方法和静态泛型方法。在定义泛型方法时,参数类型一般放到返回值前面,并且需要说明的是如果返回值类型不是void的情况下,返回值类型仍然定义为泛型。此外,调用泛型方法时不需要像泛型类和泛型接口那样指定泛型的类型,系统能够自动判断出泛型的类型,因此泛型方法的调用和普通方法没有区别。

        非静态泛型方法的语法结构:

        public <泛型表示符号> void 方法名(泛型表示符号 形式参数){}

        public <泛型表示符号> 泛型表示符号 方法名(泛型表示符号 形式参数){}

        静态泛型方法的语法够:

        public static <泛型表示符号> void 方法名(泛型表示符号 形式参数){}

        public static <泛型表示符号> 泛型表示符号 方法名(泛型表示符号 形式参数){}

        对于静态泛型方法和非静态泛型方法,除了在定义的格式上存在的细微区别外,还要特别注意,静态泛型方法时无法访问类上定义的泛型的,也就是说如果我们定义了一个泛型类,在这个类中定义静态泛型方法时必须在static后面定义泛型,而不能直接使用类上定义的泛型。

泛型方法与可变参数

        在泛型方法中和普通方法一样,传入的参数也可以是任意类型,包括像数组这种可变参数依旧可以传入方法,不过在泛型方法中用泛型定义可变参数的类型时要采用特殊的语法结构进行说明,它的具体语法格式为:

        public  (static) 泛型表示符号 泛型表示符号(void) 方法名 (泛型表示符号. . . 可变参数名称){}

在这个语法结构中要特别注意泛型表示符号与可变参数名称之间的符号. . .  ,它是用来区分普通参数和可变参数的标志。 

演示代码

package com.generic.demo;public class MethodGeneric01 {public <T> void setName(T name){System.out.println(name);}public <T> T getName(T name){return name;}public static <T> void setFlag(T flag){System.out.println(flag);}public static <T> T getFlag(T flag){return flag;}public <T> void method (T...args){for(T t:args){System.out.print(t+"\t");}System.out.println();}}
package com.generic.demo;public class TestMethodGeneric01 {public static void main(String[] args) {MethodGeneric01 methodGeneric01 = new MethodGeneric01();methodGeneric01.setName(123);methodGeneric01.setName("jiuju");MethodGeneric01 methodGeneric02 = new MethodGeneric01();String name1 = methodGeneric02.getName("dede");System.out.println(name1);Integer name2 = methodGeneric02.getName(1234);System.out.println(name2);System.out.println("___________________");//静态方法无法使用类上定义的泛型MethodGeneric01.setFlag("liuyi");Integer flag = MethodGeneric01.getFlag(123);System.out.println(flag);System.out.println("_____________________________");//泛型与可变参数:数组String[] arr1 = new String[]{"a","b","c"};Integer[] arr2 = new Integer[]{1,2,3,4};methodGeneric01.method(arr1);methodGeneric01.method(arr2);}
}

 

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

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

相关文章

网络安全实训Day15

写在前面 电子垃圾&#xff0c;堂堂恢复连载。本来不想分天数梳理了&#xff0c;但是最后要写实训报告&#xff0c;报告里还要有实训日记记录每日学的东西&#xff0c;干脆发这里留个档&#xff0c;到时候写报告提供一个思路。 网络空间安全实训-渗透测试 渗透测试概述 定义 一…

[Android14] SystemUI的启动

1. 什么是System UI SystemUI是Android系统级应用&#xff0c;负责反馈系统及应用状态并与用户保持大量的交互。业务主要涉及的组成部分包括状态栏(Status Bar)&#xff0c;通知栏(Notification Panel)&#xff0c;锁屏(Keyguard)&#xff0c;控制中心(Quick Setting)&#xff…

北京车展创新纷呈,移远通信网联赋能

时隔四年&#xff0c;备受瞩目的2024&#xff08;第十八届&#xff09;北京国际汽车展览会于4月25日盛大开幕。在这场汽车行业盛会上&#xff0c;各大主流车企竞相炫技&#xff0c;众多全球首发车、概念车、新能源车在这里汇聚&#xff0c;深刻揭示了汽车产业的最新成果和发展潮…

Rust中的函数指针

什么是函数指针 通过函数指针允许我们使用函数作为另一个函数的参数。函数的类型是 fn &#xff08;使用小写的 ”f” &#xff09;以免与 Fn 闭包 trait 相混淆。fn 被称为 函数指针&#xff08;function pointer&#xff09;。指定参数为函数指针的语法类似于闭包。 函数指…

前端到全栈进阶之“前端框架”

从前端入门到全栈-系列介绍 你会学到什么&#xff1f; 可能学不到什么东西&#xff0c;该系列是作者本人工作和学习积累&#xff0c;用于复习 系列介绍 现在的 Web 前端已经离不开 Node.js&#xff0c;我们广泛使用的 Babel、Webpack、工程化都是基于 Node 的&#xff0c;各…

react useEffect中window.removeEventListener没生效问题解决

在useEffect中写入window.removeEventListener没有生效&#xff0c;代码如下 useEffect(() > {const handleResize () > {console.log(window.innerWidth, window.innerHeight);};window.addEventListener(resize, handleResize);return () > {window.removeEventLi…

TiDB-PCTP考试复习

前言&#xff1a;本文仅作学习交流使用&#xff0c;对应《TiDB 数据库管理&#xff08;303&#xff09;》 补充&#xff1a;本文章仅用于个人学习&#xff0c;未经PingCAP书面许可&#xff0c;任何单位或个人不得将文档内容用于商业目的&#xff0c;或对本文章进行转载、编辑、…

商城数据库88章表36~39

schooldb库——utf8字符集——utf8_general_ci排序规则 先创建库&#xff0c;再去使用下列的DDL语句。 &#xff08;36&#xff09;DDL——操作记录表 CREATE TABLE huang_log_operates (operateid int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,staffid int(11) NOT NUL…

使用Keil移植工程时修改单片机型号参数

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 当使用Keil对STM32系列单片机开发时&#xff0c;如果使用的是库函数&#xff0c;那么不同型号单片机的工程项目文件是可以直接移植的。只需要按照下面的步骤修改对应的芯片&#xff0c;就可以直接将工程移植过去&a…

RabbitMQ(高级)笔记

一、生产者可靠性 &#xff08;1&#xff09;生产者重连&#xff08;不建议使用&#xff09; logging:pattern:dateformat: MM-dd HH:mm:ss:SSSspring:rabbitmq:virtual-host: /hamllport: 5672host: 192.168.92.136username: hmallpassword: 123listener:simple:prefetch: 1c…

hive启动beeline报错

问题一在zpark启动集群报错 出现上面的问题执行以下代码 chmod 777 /opt/apps/hadoop-3.2.1/logs 问题二启动beeline报错 执行 cd /opt/apps/hadoop-3.2.1 bin/hadoop dfsadmin -safemode leave 问题三执行查询语句报错 执行 set hive.exec.mode.local.autotrue;

flutter 解决ExpandableText组件三个点调整颜色问题

文章目录 前言一、相关代码总结 前言 最近写flutter项目&#xff0c;在使用ExpandableText时解决了一些问题&#xff0c;下面是解决方案&#xff0c;希望帮助到大家。 一、相关代码 1、代码如下&#xff1a; 2、我们设置linkColor就能设置ExpandableText三个点的颜色 Expand…

Spring Boot Admin

概述 Spirng Boot Admin 登录页面 Spring Boot Admin是一个用于管理Spring Boot应用的监控工具,它允许你查看和管理多个Spring Boot应用实例。用于应用信息进行界面化的展示&#xff0c;常常辅助我们开发人员快速查看服务运行状态在微服务架构中&#xff0c;Spring Boot Admin通…

微信小程序:6.事件

什么事事件 事件就是渲染层到逻辑层的通讯方式&#xff0c;比如提交表单&#xff0c;按钮点击都可以看作一个事件。 小程序中常用的事件 事件对象属性列表 当事件回调时&#xff0c;会收到一个事件对象event&#xff0c;他详细属性如夏表所示&#xff1a; target和curren…

微信小程序关于主包大小不能超过1.5MB的问题

常规的解决办法有以下几种 1、把资源文件改成远程服务器的&#xff0c;比如png这些 2、进入如图的分析页面&#xff0c;能明确知道你哪个插件包太大&#xff0c;我这里之前echart的包就1mb&#xff0c;现在给他缩减到了500kb的样子 3、解决vant等npm包太大的问题&#xff0c…

map与forEach的区别

JavaScript中的map和forEach都是数组原型上的方法&#xff0c;它们都可以用来遍历数组&#xff0c;但是它们之间存在一些基本的区别&#xff1a; 1.map方法&#xff1a; map会创建一个新数组&#xff0c;其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 它返回…

SpringSecurity + Oauth2 + jwt实现单点登录

文章目录 前言一、springsecurity oauth2 redis方式的缺点二、oauth2认证的4种模式的选择三、认证服务器的编写 第一步、创建WebSecurity配置类第二步、创建jwt仓库配置类第三步、创建UserDetailsService类第四步、创建认证服务器配置类 四、测试认证服务器的功能 1.创建Login…

【文章复现】基于主从博弈的社区综合能源系统分布式协同 优化运行策略

随着能源市场由传统的垂直一体式结构向交互竞争型 结构转变,社区综合能源系统的分布式特征愈发明显,传统 的集中优化方法难以揭示多主体间的交互行为。该文提出一 种基于主从博弈的社区综合能源系统分布式协同优化运行 策略,将综合能源销售商作为领导者,新能源冷热电联供运…

vivado 使用“链路 (Links)”窗口查看和更改链路设置

使用“链路 (Links) ”窗口查看和更改链路设置 创建链路后 &#xff0c; 就会将其添加到“ Links ”视图 &#xff08; 请参阅下图 &#xff09; 中 &#xff0c; 该视图是更改链路设置和查看状态的主要方法 &#xff0c; 也是最佳方法。 “ Links ”窗口中的每一行都对应 1 …

Qt窗口全屏显示方法

要在Qt中设置窗口全屏显示&#xff0c;可以采取以下方法&#xff1a; 使用showFullScreen()方法&#xff1a; 对于QWidget对象&#xff0c;可以直接调用showFullScreen()方法来实现全屏显示。 QWidget w; w.showFullScreen();使用setWindowState()方法&#xff1a; 可以通过…