当前位置:

首页 > 编程开发 > 如何使用Java泛型方法

如何使用Java泛型方法

泛型方法一般定义如下,即方法的前面加了个publicclassFTest{publicListf(Tt){...};}三种泛型参数推断方式:1、直接在f()前面加确定泛型fTest.f(xxx)2、通过输入参数确定,下面这个推断为Integerintnumber=0;fTest.f(number)3、可通过返回值确定Listlist=fTest.f(xxx);Q:下面这段代码哪里有问题?是toString()那里吗?publicclassA{publicstaticvoidtest(Tt){System.

本文目录

    泛型方法

    一般定义如下,即方法的前面加了个

    public class FTest {
    	public  List f(T t){...};
    }

    三种泛型参数推断方式:

    1、直接在f()前面加确定泛型

    fTest.f(xxx)

    2、通过输入参数确定, 下面这个推断为Integer

    int number = 0;
    fTest.f(number)

    3、可通过 返回值 确定

    List list = fTest.f(xxx);

    Q: 下面这段代码哪里有问题? 是toString()那里吗?

    public class A {
    	public static void  test(T t){
      		System.out.println(t.toString());  
      }
    }

    A:test是static方法, 因此无法感知A实例里的T
    需要改成
    public static void test(T t)

    toString()那里没问题,toString就是Object的方法。

    泛型参数和类型消除

    Q: 泛型参数T在运行时,会变成什么?
    A: 统一变成Object且不包含任何类型信息。

    Q: 泛型参数T可以可以使用instanceof做比较吗?

    class A {
       void f(Object arg)
       if(arg instanceof T) {
    	  ...
       }
    }

    A: 不能,编译器会报错。

    Q: 泛型参数T可以进行new T()或者new T[]操作吗?
    A: 不能,编译器会报错。

    如何使用Java泛型方法

    Q: 能调用泛型参数对象里的方法吗?

    T.f();

    A: 只能调用Object的方法。

    Q: 可以用T做强制转化吗?

    T t = (T)object;

    A: 能运行, 但不会真正发生转型, 编译时会触发waring警告。

    新建泛型对象时的问题

    先假定有2个类, 基类Parent 和子类Child

    class Parent{}
    class Child extends Parent{}

    回答以下问题:
    Q:下面这句话有问题吗?

    List list = new ArrayList()

    A:有问题,编译就错误了。 List和ArrayList并不存在父子类的关系

    Q:

    List list = new ArrayList();

    这个list有什么特点?

    A:这个list可以调用A a = list.get(), 但是不能list.add(new Parent())

    • 原因:
      list.get()所做的操作是在返回时, 把内部的 强转成Parent, 是合理的,任何Parent的子类都可以转成Parent
      list.add(new Parent())所做的操作是在输入时, 把外部的A转成内部的, 这是不合理的,因为我们不知道这个Parent对象可以转成哪个Parent的子类。

    Q:

    List list = new ArrayList();

    这个list有什么特点?
    下面谁会报错

    list.add(new Child())
    list.add(new Parent())
    Parent a= list.get();
    Child b = list.get()

    A:截图如下:

    如何使用Java泛型方法

    • Child c = list.get() 或者Parent p = list.get()所做的操作是在返回时, 把内部的 强转成外部的Parent或者child, 是不合理的, 因为编译器觉得child的父类 不一定 能转成parent或者child,所以禁止了这种行为( 比如parent的父类是object, 但object不一定就能转成parent或者child)。*list.add(new Child())所做的操作是在输入时, 把外部的child或者parent转成内部的, 这是合理的,因为child和parent一定能转成child的父类。

    Q:

    List list = new ArrayList();

    这个list有什么特点?

    A:get和add都不行,只能做remove等无返回值无输入A的操作。
    PS: 注意,不是说不能调用get或add方法, 而是调用get或add时,不能使用A这个对象去操作。
    即无法做add(A) 或者 A a = get(0)
    但是可以做add(object) 或者Object o = get(0)
    因为?可以转为Object, 但是无法转为A。

    Q:下面这个代码会报错吗?

       List fruitList = new ArrayList<>();
       fruitList.add(new Fruit());
       List appleList = new ArrayList<>();
       appleList.add(new Apple());
       fruitList.addAll(appleList);
       System.out.println(fruitList);

    A:不会报错。会正常打印结果。

    如何使用Java泛型方法

    PECS原则
    注意PECS原则和上面的区别!
    上面之前提到的? extend或者? supert, 都是在声明对象的时候用的。
    而PECS原则是用于泛型对象的方法输入参数!

    假设有一个类定义如下:

    public static class MyList {
        List list = new ArrayList<>();
    
        // 把输入参数塞给自己,类似于生产操作
        public void pushList(List t) {
            list.addAll(t);
        }
    
        // 把自己的内容塞给输入参数,类似于让输入参数做消费。
        public void pollList(List t) {
             t.addAll(list);
        }
    }

    则T就是泛型参数。

    Q:下面代码能正常运行吗?

    MyList myList = new MyList<>();
    
    List intList = new ArrayList<>();
    myList.pushList(intList);
    
    List objectList = new ArrayList<>();
    myList.pollList(objectList);

    A:不能正常运行, pushList和pollList都会报错

    因为编译器检查后,认为 List和List不是一个东西!

    Q: 如果上文要支持pushList,应该怎么修改pushList方法的定义?
    A:改成这样:

    // 把输入参数塞给自己,类似于生产操作
    public void pushList(List t) {
        list.addAll(t);
    }

    即编译器认为,List 和List是一个东西,允许!

    Q: 如果要支持pollList,怎么修改定义?
    A:

    // 把自己的内容塞给输入参数,类似于让输入参数做消费。
    public void pollList(List t) {
        t.addAll(list);
    }

    因为是把自己的东西塞给输入参数, 而想要能塞进去,必须保证自己这个T,是输入参数的子类,反过来说,输入参数必须是T的父类,所以用super
    于是编译器认为,List 和List是一个东西,允许!

    PECS原则出自Effective Java, 注意只是一个编程建议而已!

    • 如果有一个类A,泛型参数为T

    • 如果他一般只用于接收输入容器List后,塞入自己内部的T容器, 则类A就叫生产者, 因此输入参数最好定义为最好, 以便能接收任何T子类的容器。

    • 如果他一般只用于接收输入容器后List, 把自己内部的T元素塞给它, 那么这个类A就叫消费者, 输入参数最好定义为\ 最好, 以便自己的T元素能塞给任何T元素的父类容器。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    为什么要购买正版软件?
    01 官方授权

    授权来源透明,订单与许可信息可随时查询。

    02 即时交付

    付款成功后自动发放激活信息,支持订单追踪。

    03 中文协助

    安装、激活、迁移与续费问题都有专人响应。

    04 长期可用

    提供升级提醒与授权管理,换机时也能轻松迁移。

    网站备案号:苏ICP备2026018738号-1 联系邮箱:bd@zhengruan.com 网站地图

    Copyright ©2018-2026