Java 方法前面加 <T> 是做什么?泛型方法

embedded/2024/10/19 9:26:05/

在 Java 中,方法前面加上 <T> 表示该方法是一个泛型方法泛型方法允许你在方法签名中指定一个或多个类型参数,从而使得该方法可以处理多种类型的对象。这增加了代码的灵活性和复用性。

一、基本语法

java"><T1, T2, ..., Tn> 返回类型 方法名(形参列表) {// 方法体
}
  • <T1, T2, ..., Tn>:类型参数列表,可以有一个或多个类型参数。
  • 返回类型:方法的返回类型,可以是具体的类型,也可以是类型参数。
  • 方法名:方法的名称。
  • 形参列表:方法的参数列表,可以使用类型参数作为参数类型。

 二、代码示例

1. 单个类型参数的泛型方法

 假设现在富士康(Foxconn)要生产一批手机,它给手机厂商定下了一个规范:

java">package com.study.genericity.entity;/*** 富士康的手机生产规范*/
public abstract class MobilePhone {abstract void produce();
}

 OPPO、Huawei 都按照 富士康 的规范(extends MobilePhone)生产手机:

java">package com.study.genericity.entity;
import lombok.AllArgsConstructor;@AllArgsConstructor
public class OPPO extends MobilePhone {/** 型号 */private String model;/** 颜色 */private String color;/** 运行内存 */private String ram;/** 存储 */private String rom;@Overridepublic void produce() {System.out.println("正在生产 OPPO手机 :型号-"+model+" 颜色-"+color+" 运行内存-"+ram+" 存储容量-"+rom);}
}
----------------------------------------
package com.study.genericity.entity;
import lombok.AllArgsConstructor;@AllArgsConstructor
public class Huawei extends MobilePhone {/** 型号 */private String model;/** 颜色 */private String color;/** 是否折叠 */private boolean foldOrNot;/** 运行内存 */private String ram;/** 存储 */private String rom;@Overridepublic void produce() {String description = "正在生产 华为手机 :"+(foldOrNot?"折叠屏 ":"")+model+" "+color+" "+ram+" "+rom;System.out.println(description);}
}

 富士康 为他们开了一条通用生产线生产手机:

java">package com.study.genericity.entity;public class Foxconn {/** 富士康通用生产线 */public static void produce(MobilePhone mobilePhone) {mobilePhone.produce();}public static void main(String[] args) {OPPO oppo = new OPPO("Find X7", "白日梦想家", "12GB", "256GB");produce(oppo);Huawei huawei = new Huawei("Pocket 2", "洛可可白", true, "12GB", "256GB");produce(huawei);}
}
输出:
正在生产 OPPO手机 :型号-Find X7 颜色-白日梦想家 运行内存-12GB 存储容量-256GB
正在生产 华为手机 :折叠屏 Pocket 2 洛可可白 12GB 256GB

 这个时候来了苹果,他们委托 富士康 生产新版 iPhone。

不过苹果 它财大气粗,它有自己的手机生产规范:

java">package com.study.genericity.entity;/*** 苹果自己的移动产品生产规范*/
public  abstract class AppleMobile {abstract void producePhone();
}
----------------------------------------
package com.study.genericity.entity;import lombok.AllArgsConstructor;@AllArgsConstructor
public class Apple extends AppleMobile {/** 型号 */private String model;/** 颜色 */private String color;/** 运行内存 */private String ram;/** 存储 */private String rom;@Overridepublic void producePhone() {System.out.println("正在生产 尊贵的iPhone :"+model+" "+color+" "+ram+" "+rom);}
}

 富士康 本来想拒绝,因为苹果的生产流程已经继承了 AppleMobile 规范, 无法再继承 MobilePhone 规范,两个规范并不兼容(Java 单继承)。但如果为苹果单开一条生产线,成本又特别高昂。

java">package com.study.genericity.entity;public class Foxconn {/** 富士康通用生产线 */public static void produce(MobilePhone mobilePhone) {mobilePhone.produce();}/** 为苹果单开一条流水线 */public static void produce(AppleMobile appleMobile) {appleMobile.producePhone();}public static void main(String[] args) {OPPO oppo = new OPPO("Find X7", "白日梦想家", "12GB", "256GB");produce(oppo);Huawei huawei = new Huawei("Pocket 2", "洛可可白", true, "12GB", "256GB");produce(huawei);Apple apple = new Apple("iPhone 16 Pro", "白", "16GB", "128GB");produce(apple);}
}
输出:
正在生产 OPPO手机 :型号-Find X7 颜色-白日梦想家 运行内存-12GB 存储容量-256GB
正在生产 华为手机 :折叠屏 Pocket 2 洛可可白 12GB 256GB
正在生产 尊贵的iPhone :iPhone 16 Pro 白 16GB 128GB

 这可愁坏了 富士康 的老总,这个时候,聪明的工程师 小林 为老板想了一个办法,他用 泛型方法 的方式,定义了一条通用的流水线,可以忽略类型规范:

java">package com.study.genericity.entity;import java.util.function.Consumer;public class Foxconn {/** 用 泛型方法 定义通用生产流水线 */public static <T> void produce(Consumer<T> consumer, T phone) {consumer.accept(phone);}public static void main(String[] args) {OPPO oppo = new OPPO("Find X7", "白日梦想家", "12GB", "256GB");produce(OPPO::produce, oppo);Huawei huawei = new Huawei("Pocket 2", "洛可可白", true, "12GB", "256GB");produce(Huawei::produce, huawei);Apple apple = new Apple("iPhone 16 Pro", "白", "16GB", "128GB");// 苹果 定制化生产produce(Apple::producePhone, apple);}
}
输出:
正在生产 OPPO手机 :型号-Find X7 颜色-白日梦想家 运行内存-12GB 存储容量-256GB
正在生产 华为手机 :折叠屏 Pocket 2 洛可可白 12GB 256GB
正在生产 尊贵的iPhone :iPhone 16 Pro 白 16GB 128GB

富士康 老板高兴坏了,因为这条流水线太好用,老板甚至放弃了自定义的手机生产规范 MobilePhone,给手机厂商更高的自由度(不用再继承 MobilePhone),去生产定制化的手机产品:

java">package com.study.genericity.entity;
import lombok.AllArgsConstructor;@AllArgsConstructor
public class Huawei {/** 型号 */private String model;/** 颜色 */private String color;/** 是否折叠 */private boolean foldOrNot;/** 运行内存 */private String ram;/** 存储 */private String rom;/** 定制化生产 */public void produceHuawei() {String description = "正在生产 华为手机 :"+(foldOrNot?"折叠屏 ":"")+model+" "+color+" "+ram+" "+rom;System.out.println(description);}
}
---------------------------------------------
package com.study.genericity.entity;
import lombok.AllArgsConstructor;@AllArgsConstructor
public class OPPO {/** 型号 */private String model;/** 颜色 */private String color;/** 运行内存 */private String ram;/** 存储 */private String rom;/** 定制化生产 */public void produceOPPO() {System.out.println("正在生产 OPPO手机 :型号-"+model+" 颜色-"+color+" 运行内存-"+ram+" 存储容量-"+rom);}
}
---------------------------------------------
package com.study.genericity.entity;import java.util.function.Consumer;public class Foxconn {/** 用 泛型方法 定义通用生产流水线 */public static <T> void produce(Consumer<T> consumer, T phone) {consumer.accept(phone);}public static void main(String[] args) {OPPO oppo = new OPPO("Find X7", "白日梦想家", "12GB", "256GB");// OPPO 定制化生产produce(OPPO::produceOPPO, oppo);Huawei huawei = new Huawei("Pocket 2", "洛可可白", true, "12GB", "256GB");// 华为 定制化生产produce(Huawei::produceHuawei, huawei);Apple apple = new Apple("iPhone 16 Pro", "白", "16GB", "128GB");// 苹果 定制化生产produce(Apple::producePhone, apple);}
}
输出:
正在生产 OPPO手机 :型号-Find X7 颜色-白日梦想家 运行内存-12GB 存储容量-256GB
正在生产 华为手机 :折叠屏 Pocket 2 洛可可白 12GB 256GB
正在生产 尊贵的iPhone :iPhone 16 Pro 白 16GB 128GB


http://www.ppmy.cn/embedded/121042.html

相关文章

宠物空气净化器该怎么选?希喂、美的、有哈这三款有推荐的吗?

终于要到国庆了&#xff0c;这可是打工人除春节外最长的假期&#xff01;在外上班后&#xff0c;回家的次数越来越少了&#xff0c;这次国庆肯定要回去陪陪父母。这票是真难买啊&#xff0c;候补了我一个多星期才买到。本来以为最困难的问题已经解决了&#xff0c;又想到我家猫…

回归正则化

Lasso回归&#xff08;Least Absolute Shrinkage and Selection Operator&#xff09;是一种线性回归方法&#xff0c;它通过添加L1正则化项来约束模型的复杂性。具体来说&#xff0c;Lasso回归的目标是最小化以下损失函数&#xff1a; 其中&#xff0c;第一项是均方误差&…

C++软件试用期检测

测试 #include "TrialCheck.h" int main(int argc, char*argv[]) {TrialCheck ckeck;bool isOk ckeck.isUseful("20200601", "20200705");printf("%s", isOk ? "欢迎试用" : "试用期已过&#xff0c;请先注册"…

Docker从入门到精通_01 Docker:引领云计算的新浪潮

Docker从入门到精通_01 Docker&#xff1a;引领云计算的新浪潮 云计算作为信息技术领域的重要支柱&#xff0c;正以前所未有的速度发展。然而&#xff0c;传统的虚拟化架构在资源利用、部署效率、应用扩展等方面已逐渐显露出其局限性。在这样的背景下&#xff0c;容器云技术应…

js逆向——webpack实战案例(一)

今日受害者网站&#xff1a;https://www.iciba.com/translate?typetext 首先通过跟栈的方法找到加密位置 我们跟进u函数&#xff0c;发现是通过webpack加载的 向上寻找u的加载位置&#xff0c;然后打上断点&#xff0c;刷新网页&#xff0c;让程序断在加载函数的位置 u r.n…

vue中的vuex详解

文章目录 vue中的vuex详解一、引言二、Vuex 的核心概念1、State1.1、定义 State1.2、访问 State 2、Mutation2.1、定义 Mutation2.2、提交 Mutation 3、Action3.1、定义 Action3.2、分发 Action 4、Getter4.1、定义 Getter4.2、使用 Getter 5、Module5.1、定义 Module 三、安装…

Vue 组件的三大组成部分详解

文章目录 模板&#xff08;template&#xff09;脚本&#xff08;script&#xff09;样式&#xff08;style&#xff09;总结 在 Vue.js 中&#xff0c;组件是构建用户界面的重要基石。一个 Vue 组件通常由三个主要部分组成&#xff1a;模板&#xff08;template&#xff09;、…

C语言 | 第四章 | 常量 运算符-1

P 31 课后练习评讲 2022/8/24 一、题目 代码演示:第一题 #include<stdio.h>void main(){// 分析&#xff1a;使用不同的变量来保存对应的数据char name[10] "张三"; // 字符数组&#xff0c;存放字符串short age 23;float score 78.5f;char gender M; …