Java 泛型

Java 泛型是什么?一文带你吃透泛型 它是一个泛型类,而我之前使用的时候并没有传递,说明 Java 语法是允许的,这个时候传递的类型是 Object 类,虽然它是所有类的父类,可以存储任意的类型,但是在遍历、获取元素时需要原来的类型就要进行强制转换。泛型接口有两使用方式,要么在实现接口时确定泛型类的类型,要么在实现接口时先不确定泛型类类型,而在实例化对象时再确定。这个时候就会出现一些问题,假如往链表里存储了许多不同类型的数据,在强转的时候就要判断每一个原来的类型,这样就很容易出现错误。,泛型在类中可以创建变量,也可以作为方法的参数或者返回值。 阅读详情

首先,肘子假设各位读者朋友已经了解了泛型的基本概念了。


同样以Head First Java的习题开头(P576练习)
下面哪些语句可以通过编译么?

//Dog是Animal的子类
//[1]
ArrayList<Dog> dogs1 = new ArrayList<Animal>();
//[2]
ArrayList<Animal> animals1 = new ArrayList<Dog>();
//[3]
List<Animal> list = new ArrayList<Animal>();
//[4]
ArrayList<Dog> dogs = new ArrayList<Dog>();
//[5]
ArrayList<Dog> dogs = new ArrayList<Dog>();
ArrayList<Animal> animals = dogs;
//[6]
ArrayList<Dog> dogs = new ArrayList<Dog>();
List<Dog> dogList = dogs;
//[7]
ArrayList<Object> objects = new ArrayList<Object>();
List<Object> objList = objects;
//[8]
ArrayList<Object> objs = new ArrayList<Dog>();

想要解决问题需要理解好一下几个概念:

泛型,继承与子类型

如果class Dog extends class Animal,即类Dog继承类Animal,那么Dog对象可以赋值给Animal对象。比如String是Object的子类,Integer,Float是Number的子类,所以以下的赋值是合法的:

String str = "1234";
Object obj = str;

public void foo(Number n) {}
foo(new Integer(6));
foo(new Float(10.001));

且来看看ArrayList的源码:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, ...
        {
        ...
        }
//所以ArrayList<E>是AbstractList<E>,List<E>的子类
//ArrayList<Dog>的父类是AbstractList<Dog>和List<Dog>,而ArrayList<Dog>与ArrayList<Cat>都不是ArrayList<Animal>的子类,ArrayList<Dog>与ArrayList<Cat>的父类是Object

那么现在看回文章开头的习题:
所以能够通过编译的是[3][4][6][7][8]。

泛型命名规范

为了与java关键字区别开来,java泛型参数只是使用一个大写字母来定义。各种常用泛型参数的意义如下:
- E — Element,常用在java Collection里,如:List,Iterator,Set
- K,V — Key,Value,代表Map的键值对
- N — Number,数字
- T — Type,类型,如String,Integer等等
- S,U,V etc. - 2nd, 3rd, 4th 类型,和T的用法一样

参考:java泛型编程

泛型不协变(covariant)

说白了,就是数组与ArrayList的对比。

Java 语言中的数组是协变的(covariant),比如, Integer extends Number,那么不仅 Integer是 Number,而且 Integer[]也是 Number[],在要求 Number[]的地方完全可以传递或者赋予 Integer[]。(更正式地说,如果 Number是 Integer的超类型,那么 Number[]也是 Integer[]的超类型)。您也许认为这一原理同样适用于泛型类型 ——
List< Number>是 List< Integer>的超类型,那么可以在需要 List< Number>的地方传递 List< Integer>。不幸的是,情况并非如此。
不允许这样做有一个很充分的理由:这样做将破坏要提供的类型安全泛型。如果能够将 List< Integer>赋给 List< Number>。那么下面的代码就允许将非 Integer的内容放入 List< Integer>:

 List<Integer> li = new ArrayList<Integer>(); 
 List<Number> ln = li; // illegal 
 ln.add(new Float(3.1415));
 //ln是 List< Number>,所以向其添加 Float似乎是完全合法的。但是如果 ln是 li的别名,那么这就破坏了蕴含在 li定义中的类型安全承诺 —— 它是一个整数列表,这就是泛型类型不能协变的原因。

这也就很好解释下面的代码为什么编译不过了:

class Test {
    public void takeAnimals(Animal[] animals) {}
    public void takeAnimals(ArrayList<Animal> animals){}
    public void go() {
        Dog[] dogs = {new Dog(), new Dog(), new Dog()};
        Animal[] animals = {new Animal(), new Dog(), new Cat()};
        takeAnimals(dogs);
        takeAnimals(animals);

        ArrayList<Animal> animals2 = new ArrayList<>();
        animals.add(new Animal());
        animals.add(new Dog());
        animals.add(new Cat());
        takeAnimals(animals2);

        ArrayList<Dog> dogs2 = new ArrayList<>();
        dogs2.add(new Dog());
        dogs2.add(new Dog());
        takeAnimals(dogs2); //编译不过哦o(0-0)o
    }

}

引用:Java 理论和实践: 了解泛型

如何写泛型

网络上有很详细的讲解了,肘子觉得写得比较清楚的是
Java泛型:泛型类,泛型接口,泛型方法

但是肘子觉得比较实用的是在输出一些信息会用到泛型方法:

public class Test {
    public static <T> void print(T t) {
        System.out.println(t);
    }

    public static <T> void print(T... t) {
        for(T it: t)
            System.out.println(it);
    }
    public static void main(String[] args){
        print("hello world");
        print(123);
        print(12.09);
        print(false);

        print(123456, "hahhahah", true, 145.098);
    }
}

这个在写小程序的时候,要输出一些primitive数据类型的变量时是不是有点方便呢?

以上。
争取这周把书啃完。

【泛型】Java中的泛型,泛型类,泛型接口,泛型方法,泛型擦除 这篇文章总结一下Java中的泛型相关知识点,包括:泛型概念、泛型优缺点、泛型通配符、泛型上下界、泛型使用(泛型类、泛型接口、泛型方法)、泛型擦除等内容。 一、泛型概念 (1)什么是泛型 什么是泛型??? 泛型(Generic),是一种参数化数据类型,它允许我们在编写程序代码的时候不用具体指定需要什么数据类型,而是等到具体使用的时候,将数据类型以参数的形式传递给程序,这就是泛型程序设计。 (2)为什么需要泛型 我们来看看下面这个栗子 假设现在有个需求,通过集合保存元素,需要保存String字 阅读详情

相关推荐

TSmaster CANFD配置避坑指南:为什么你的PCAN盒不支持最新版本?

本文针对TSmaster配置PCAN硬件进行CANFD通信时的常见问题,提供了详细的避坑指南。重点解析了CANFD配置中TSEG1等关键参数的理解误区,并深入探讨了TSmaster新版本与PCAN硬件驱动之间的兼容性变化,帮助工程师快速定位并解决连接失败或无法发送CANFD报文等问题。

alpha的博客 541

Java的ArrayList源码剖析

ArrayList深度剖析前言一、ArrayList数据结构二、ArrayList的常用APIaddremovesetget 前言 系统性的细节性的去学习一个知识可能绝大多数同学的初衷都是为了应付面试。因为平时这些集合类都是封装好的API,我们只管调用就可以了。最差的情况可能就是会因为一些错误性的使用而出现IndexOutOfBoundsException或者IllegalArgumentException等异常问题。 那么我们如何去学会深度理解跟使用一个集合?在我的理解看来,主要掌握以下两点 1.了解这

qq_42865087的博客 353

8位可控加减法电路设计

一、设计要求   利用Logisim平台中现有运算部件构建一个8位可控加减法器,可支持八位加减法,利用已经封装全加器和逻辑门进行连接,要求实现相应的输出,判断是否溢出。 二、方案设计 实验原理: [A]补+[B]补 = [A+B]补(mod2^n+1)   公式1        [A-B]补 = [A]补+[-B]补(mod2^n+1)    公式2 FA为全加器,利用全加器实现加减法,难点在于实验减法,对输入的[Y]补各位取反加一即为[-Y]补,利用公式2,就可以将减法转化为加法再利用全加

qq_51700383的博客 1万+

为什么创建集合对象时用List<String> list = new ArrayList<String>()而不是用ArrayList<Object> list = new ArrayList<>()

为什么创建集合对象时用List<String> list = new ArrayList<String>()而不是用ArrayList<Object> list = new ArrayList<>()呢? 道理很简单,我们知道List是一个接口,ArrayList是一个类,ArrayList继承了List接口并实现了它,那么ArrayList就有很多List中没有定义的方法,如果我么在编程中使用ArrayList<Object> list = n

毕业势必进大厂的博客 2266

从零到一:手把手教你构建自定义ReaxFF力场参数

本文手把手教你从零构建自定义ReaxFF力场参数,详解反应力场的动态键序机制与参数化逻辑。通过LAMMPS实战演示,涵盖训练数据准备、参数优化算法选择及性能优化技巧,助力研究人员精准模拟化学反应过程。适用于材料科学、催化研究等领域,特别适合已掌握分子动力学基础的进阶用户提升力场开发能力。

weixin_28365523的博客 1056

从宏观到街道:如何利用七普数据为WorldPop人口栅格做“本地化”校准?

本文探讨了如何利用第七次全国人口普查(七普)数据对WorldPop人口栅格进行本地化校准,以提高街道级别的人口分布精度。通过分析数据偏差、选择适当的技术路线和工具(如Arcgis和栅格计算器),文章详细介绍了从宏观到街道的校准实践,帮助规划公共卫生资源和优化城市基础设施。

janckywong963的专栏 511

测试人员应该知道的Redis知识(六) Set

一、概述 Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1) 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。 Set类型是我们工作中经常会用的一种数据类型,我们经常用来进行去重等操作,今天我们一起来看一下针对Set类型,我们工作中常用的一些命令。 二、sadd/smemb...

Frank_girl的博客 959

Labelme安装教程(附Anaconda安装教程)

本文详细介绍了如何安装Anaconda和Labelme,还提供了常见问题的解决建议。

HanYan_ing的博客 1万+

Java多态的理解--父类引用指向子类的对象

1、定义:在程序中定义的某个引用变量具体所指向的类型和调用的方法在编码时并不能确定,而只有在运行的时候才能确定。   2、简单理解:你定义的引用变量是父类型,而你创建的对象是子类型,用这个父类型的引用变量指向这个子类型的对象,然后当你调用这个对象的方法的时候,具体是调用的父类的还是子类的方法只有在运行的时候才能确定,可能调用的是父类的方法也有可能调用的子类的方法,这样不用修改代码,就可以让...

我的博客 877

SAP ABAP CO核心扩展-ZCKMLQS 多物料工厂的评估数量结构报表(CKMLQS)

CKMLQS 只能查看单一物料工厂的评估数量结构,SAP 没有提供多物料工厂的评估数量结构报表。这篇文章将实现 CO核心扩展-ZCKMLQS 多物料工厂的评估数量结构报表。

SAP李斌,本人承诺所有原创文章均不使用任何AI生成技术,请大家放心阅读。 1089

32位快速加法器设计

32位快速加法器设计

好好学习,天天向上 3289

java 一些问题验证

java 一些问题验证

u011576406的博客 301

2020年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)

2020年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)

王老师青少年编程 990

Java之泛型

一、什么是泛型 1.背景: JAVA推出泛型以前,程序员可以构建一个元素类型为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型,否则很容易引发ClassCastException异常。 2.概念: Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。 3.好处: 类型安全 消

Beyondczn的博客 9373

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java泛型详解:Java泛型集合、泛型类、泛型方法、泛型的使用

在 Java 1.5 之前没有泛型,通常需要使用强制类型转换的方式将一种数据类型转换为另一种数据类型,这种转换要求开发者对实际参数的类型具有可预知性。对于强制类型转换错误的情况,编译器可能不会提示错误,但是在运行时会出现异常,这是一个安全隐患。 为了解决这一隐患,从 Java 1.5 开始提供了泛型。泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。本节将详...

jijiangpeng的博客 7433

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java泛型——为何要有泛型

对于String类类型来说,它是继承自Object的,而Integer的直接父类是Number,因此会有Integer无法转String的错误。泛型类是在实例化类的时候指明泛型的具体类型,那么泛型方法就是在调用方法时指明泛型的具体类型。在实现传入泛型实参的泛型接口的实现类定义中,实现类即使不声明泛型,也不会编译错误。在实现未传入泛型实参的泛型接口的实现类定义中,实现类要声明泛型,否则会编译错误。为了避免这样可能的错误,引入泛型,使编译器在编译阶段就提示不匹配的类类型。方法返回了一个更加特定的返回类型。

xiaovie的博客 1720

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Java泛型

是同时存在的,可是如果是常规的两个方法,他们的方法签名是一样的,也就是说虚拟机根本不能分别这两个方法。如果是我们自己编写Java代码,这样的代码是无法通过编译器的检查的,但是虚拟机却是允许这样做的,因为虚拟机通过参数类型和返回类型来确定一个方法,所以编译器为了实现泛型的多态允许自己做这个看起来“不合法”的事情,然后交给虚拟器去区别。如果是重载,那么子类中两个setValue方法,一个是参数Object类型,一个是Date类型,可是我们发现,根本就没有这样的一个子类继承自父类的Object类型参数的方法。

YLXCA的博客 1315

java泛型——泛型类、泛型方法、泛型接口

泛型Java 泛型Java 泛型是什么泛型类泛型类的格式泛型类举例泛型方法泛型方法的格式泛型方法举例泛型接口泛型接口的格式泛型接口举例 Java 泛型 Java 泛型是什么 官方定义: 泛型是Java SE 1.5的新特性,泛型的本质就是参数化类型,也就是说所操作的数据类型被指定为一个参数 这种参数类型可以用在类、接口和方法的创建中,分别成为泛型类、泛型接口、泛型方法 优缺点: ​ 优点:可以不用再类型转换了 ​ 缺点:降低了代码的可读性 泛型类 泛型类:当一个类要操作的引用数据类型不确定的时候,可

一个小小的码农 6583

Java泛型的其他应用——泛型接口、泛型方法、泛型数组以及泛型的嵌套设置

学习目标 掌握泛型接口的使用 掌握泛型方法的定义的及使用 掌握泛型数组的使用 掌握泛型的嵌套设置 之前所有的操作都是在类中直接使用泛型操作的,那么,对于Java来说,也可以直接在接口中定义及使用泛型。 定义泛型接口 在JDK1.5之后,不仅仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口名称后面加上,如下格式所示: [访问权限]

1万+

java泛型

文章目录1. 泛型简述2. 泛型类别2.1 泛型类2.1.1 某种实际类型,重用性不好,Holder只能拥有A类型2.1.2 Object类型,类型太泛,可以容纳所有类型2.1.3 在创建的时候可以指定只可以容纳某种类型,此后只能容纳这种类型注意:基础类型无法作为类型参数,其封装类型可以2.2 泛型接口2.3 泛型方法3. 泛型擦除3.1 泛型只在编译期有效3.2 泛型内部无法获得泛型参数的有关信...

登峰小蚁 3065

Java之泛型,什么是泛型?为什么用泛型?(泛型详解)

1.为什么会有泛型呢? 早期的Object类型可以接受任意的对象类型,但是在实际使用中,会有类型转化的问题,存在隐患,所以Java提供泛型解决这个安全问题 2.什么是泛型? 泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类...

围巢 3969

【 java 泛型】详解java泛型

java泛型可以提高java程序的类型安全,提高程序的可靠性,并且在开发中也较常用,因此还是要简单学习一下!

阿牛的博客 2069

Java【泛型】

Java的泛型说明

在下的博客 1467

java 泛型详解(普通泛型、 通配符、 泛型接口,泛型数组,泛型方法

Java代码Java代码Java代码Java代码Java代码Java代码Java代码。

2401_84619530的博客 1518

java 泛型的默认值_java泛型

1.什么是泛型泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型:泛型类 泛型接口 泛型方法作用:提高程序健壮性,简化代码泛型的默认值是Objectjdk 要1.5以上2.泛型定义/***泛型类*首先定义一个person的实体类 Person其中A代表的就是一个泛型,调用时可以自定义数据类型*/package com.temp;public class Per...

weixin_34246474的博客 1833
上一篇: Java静态与同步
下一篇: 笔记本装SSD,win10
猪杂汤饭
博客等级 码龄12年 238粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值