Java泛型(1)--集合使用泛型Generic、自定义泛型、泛型在继承上的体现、通配符的使用

文章目录

    • 泛型的概念
    • 集合中使用泛型
    • 自定义泛型结构
    • 泛型在继承上的体现
    • 通配符的使用



泛型的概念

集合容器类在设计阶段/声明阶段不能确定这个容器实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection<E>ArrayList<E><E>就是类型参数,即泛型。

所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)。

从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念,允许在创建集合时再指定集合元素的类型,正如:List<String>,这表明该List只能保存字符串类型的对象。JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。

在这里插入图片描述
在这里插入图片描述



集合中使用泛型

Collection中使用泛型:

import java.util.ArrayList;
import java.util.Iterator;/*** @Author: Yeman* @Date: 2021-09-24-15:10* @Description:*/
public class GenericTest {public static void main(String[] args) {//如下在实例化的时候在<>中填入需要的类型即可(不可以是基本数据类型)ArrayList<Integer> list = new ArrayList<>();list.add(99);list.add(0);list.add(121);//遍历方式一for (Integer integer : list){System.out.println(integer);}System.out.println("=====================");//遍历方式二Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}

Map中使用泛型:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;/*** @Author: Yeman* @Date: 2021-09-24-15:10* @Description:*/
public class GenericTest {public static void main(String[] args) {//如下如下在实例化的时候在<>中填入需要的类型即可(不可以是基本数据类型)// 注意因为Map是键值对,因此需要分别填入“键”和“值”所需要的类型HashMap<String, Integer> map = new HashMap<>();map.put("Jack",26);map.put("Marry",18);map.put("Tom",20);map.put("Lily",22);Set<Map.Entry<String, Integer>> entries = map.entrySet();Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}


自定义泛型结构

1、泛型类、泛型接口

①泛型的声明
interface List<T>{}class GenTest<K,V>{}class student <T extends Person> {}
其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以,常用T表示,是Type的缩写。

②泛型的实例化

List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();

<>里面只能是类,不能用基本数据类型填充,可以使用包装类填充。把一个集合中的内容限制为一个特定的数据类型,这就是Generic的核心思想。

泛型类可能有多个参数,此时可将多个参数一起放在尖括号内,如:<E1,E2,E3>

泛型类的构造器与非泛型一样:public GenericClass(){}
public GenericClass<E>(){}是错误的。

泛型不同的引用不能相互赋值:尽管在编译时ArrayList<String>ArrayList<Integer>是两种类型,但是,在运行时只有一个ArrayList被加载到JVM中。

在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型,因为静态成员是随着类加载而加载的,而类型的指定是在实例化时才确定的。

异常类不能使用泛型。

不能new E[],但是可以E[] elements = (E[])new Object[capacity];

父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型,子类除了指定或保留父类的泛型,还可以增加自己的泛型:

class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{
}
// 2)指定类型
class Son2 extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {
}
class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father{//等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {
}
class Person<T> {// 使用T类型定义变量private T info;// 使用T类型定义一般方法public T getInfo() {return info;}public void setInfo(T info) {this.info = info;}// 使用T类型定义构造器public Person() {}public Person(T info) {this.info = info;}
}    

2、泛型方法

方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

访问权限 是否为静态 <泛型> 返回类型 方法名(泛型标识 参数名称,...) 异常{//方法体
}
public class Test {public <E> E get(int id, E[] arry) {E result = null;return result;}
}


泛型在继承上的体现

如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!比如:String是Object的子类,但是List<String>并不是List<Object>的子类,不能相互赋值。而反过来,如下是可以的:

ArrayList<String> arrayList = new ArrayList<>();
List<String> list = arrayList;

在这里插入图片描述



通配符的使用

1、使用

比如:List<?>Map<?,?>
List<?>List<String>List<Object>等各种泛型List的父类。

读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,都包含于Object。而不能向其中添加(写入)对象。除了null,因为它是所有类型的成员:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时错误
public static void main(String[] args) {List<?> list = null;list = new ArrayList<String>();list = new ArrayList<Double>();list.add(3);//编译不通过,编译时错误list.add(null);List<String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();l1.add("AABBCC");l2.add(9);read(l1);read(l2);
}
public static void read(List<?> list) {for (Object o : list) {System.out.println(o);}
}

在这里插入图片描述
2、有限制的通配符

①<?>
允许所有泛型的引用调用

②通配符指定上限
extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=。
<? extends Number> (无穷小 , Number],只允许泛型为Number及Number子类的引用调用。<? extends Comparable>只允许泛型为实现Comparable接口的实现类的引用调用。

③通配符指定下限
下限super:使用时指定的类型不能小于操作的类,即>=。
<? super Number> [Number , 无穷大),只允许泛型为Number及Number父类的引用调用。

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

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

相关文章

linux 内存 面试,【Linux内存面试题】面试问题:查看机器配置命… - 看准网

1、查看内存大小solari&#xff1a;prtconf -vp | grep Memlinux &#xff1a;grep MemTotal /proc/meminfo2、查看硬盘大小solari&#xff1a;df -klinux &#xff1a;fdisk -l[rootssoldap ~]# fdisk -lDisk /dev/sda: 146.6 GB, 146685296640 bytes255 heads, 63 sectors/tr…

蚂蚁组件 axure 蚂蚁_蚂蚁属性细微差别

蚂蚁组件 axure 蚂蚁每隔一段时间&#xff0c;我会想起Ant属性的一些细微差别 &#xff0c;一旦忘记它们&#xff0c;在与Ant交互时会引起混乱。 特别是&#xff0c; Ant属性 通常是不可变的 &#xff08;不包括Ant 1.8以来的局部属性 &#xff09;&#xff0c;并且在其第一次设…

JavaIO流(1)--File类的使用

文章目录File类概述常用构造器常用方法File类概述 File类能新建、删除、重命名文件和目录&#xff0c;但不能访问文件内容本身&#xff0c;如果需要访问文件内容本身&#xff0c;则需要使用后续的输入/输出流。 要在Java程序中表示一个真实存在的文件或目录&#xff0c;那么必…

linux抓包提示没有权限,linux下wireshark不用sudo权限抓包包

ubuntu安装了wireshark&#xff0c;发现打不开网络接口&#xff0c;后来从网上得知要用sudo从命令行执行&#xff0c;确实可以&#xff0c;但是执行过程中一直要开一个命令行窗口&#xff0c;不爽&#xff0c;想直接用单击图标的方法运行之&#xff0c;在网上查询找到以下两个方…

Http基本身份验证在Spring Security中如何工作?

在上一篇文章中&#xff0c;您学习了如何在基于Spring安全性的Java应用程序中启用Http基本身份验证 &#xff0c;现在&#xff0c;我们将进一步进一步了解http基本身份验证在Spring安全性中的工作原理。 如果您还记得的话&#xff0c;当您使用HTTP Basic进行身份验证时&#xf…

JavaIO流(2)--IO流原理、流的分类及节点流文件流操作

文章目录IO流简介IO流原理流的分类IO 流体系节点流和处理流节点流操作IO流简介 I/O是Input/Output的缩写&#xff0c; I/O技术是非常实用的技术&#xff0c;用于处理设备之间的数据传输。如读/写文件&#xff0c;网络通讯等。 Java程序中&#xff0c;对于数据的输入/输出操作…

linux权限体系有哪些角色,详解Linux下系统权限

一、权限概述1. 什么是权限权限&#xff1a;在计算机系统中&#xff0c;权限是指某个计算机用户具有使用软件资源的权利。软件资源&#xff1a;Linux系统中&#xff0c;一切皆文件&#xff01;SO&#xff0c;这里的软件资源就是文件资源。所以&#xff0c;我们今天所讲的权限&a…

试用期java_Java 7试用资源

试用期javaJava 7为完成使用后需要关闭的资源&#xff08;例如文件&#xff0c;流&#xff0c;数据库连接和套接字&#xff09;提供了更好的资源管理。 这种语言构造称为try-with-resources语句。 完成这项工作的机制称为AutoCloseable接口。 Java 7资源类均实现此接口。 该接口…

让你的对象跑出内存,写入到磁盘或者进行网络传输,一文掌握Java对象序列化

文章目录对象序列化是什么如何让对象可序列化让对象跑出内存对象序列化是什么 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流&#xff0c;从而允许把这种二进制流持久地保存在磁盘上&#xff0c;或通过网络将这种二进制流传输到另一个网络节点。当其它程序获…

JDK 9:NotNullOrElse方法已添加到Objects类

JDK 9向Objects类添加了一些新方法&#xff0c;包括本文中突出显示的两个static方法&#xff1a; requireNonNullElse&#xff08;T&#xff0c;T&#xff09;和requireNonNullElseGet&#xff08;T obj&#xff0c;Supplier <&#xff1f;extended T>供应商&#xff09;…

linux下删除只读文件,linux – 我无法删除文件’rm:无法删除X只读文件系统’

我正在尝试删除rdiff备份文件夹,因为备份过程中出现了一些问题,需要删除它的历史记录并重试.但是,当我跑&#xff1a;rm -r -f rdiff-backup-data我在一些文件上得到以下内容&#xff1a;rm: cannot remove X: Read-only file system这是我运行mount时得到的&#xff1a;/dev/s…

让你的数据和对象有源有出路,一文打尽,Java常用IO流处理流(处理字节流文件流)缓冲流、转换流、对象流等

文章目录缓冲流转换流标准输入输出流打印流数据流对象流随机存取文件流Java NIO缓冲流 为了提高数据读写的速度&#xff0c;Java API提供了带缓冲功能的流类&#xff0c;在使用这些流类时&#xff0c;会创建一个内部缓冲区数组&#xff0c;缺省使用8192个字节(8Kb)的缓冲区。 …

异步重试_异步重试模式

异步重试当您有一段经常失败且必须重试的代码时&#xff0c;此Java 7/8库提供了丰富且简洁的API以及针对此问题的快速且可扩展的解决方案&#xff1a; ScheduledExecutorService scheduler Executors.newSingleThreadScheduledExecutor(); RetryExecutor executor new Async…

linux网卡e1000下载,Linux E1000网卡驱动分析

本分析主要针对e1000网卡,驱动源码为7.3.20-k2。本文的目的不是为了讲述如何编写驱动程序,主要是分析网卡驱动内部的实现机制。Linux-千兆网卡驱动实现机制浅析作者: Minit, 出处:博客, 责任编辑: 罗丽艳,2009-03-29 00:001.引言本分析主要针对e1000网卡&#xff0c;驱动源码为…

迈入JavaWeb第一步,Java网络编程基础,TCP网络编程URL网络编程等

文章目录网络编程概述网络通信要素要素一IP和端口号要素二网络协议TCP网络编程UDP网络编程URL网络编程Java网络编程基础网络编程概述 Java是Internet上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。 Java提…

Linux脚本双引号字符去除,shell命令去除字符串里双引号

echo \"refs/changes/84/727284/1\" | sed s/\"//gshell变量内字符替换和变量字符修改a12345123#将${a}里的第一个123替换为321b${a/123/321};echo "echo variable a"echo $aecho "echo variable b"echo $ba12345123#将${a}里的所有123替换…

一个小例子体会Java反射的动态性

背景&#xff1a;需要在程序运行时或者说某段代码运行后才能知道要创建哪个类的对象。 import java.util.Random;/*** Author: Yeman* Date: 2021-10-02-22:18* Description:*/ public class ReflectionTest {public static Object getInstance(String path) throws Exception…

Linux脚本让我选择文件,linux – 用于选择文件和打印文件大小的Awk脚本

我们在这看……select all regular files (not directories or links)到目前为止,你还没有解决这个问题,但如果你在ls -l …的输出中输入,这很容易,请选择/^-/因为目录以d开头,符号链接以l开头,依此类推.只有普通旧文件以 – 开头.现在print out the number of files followed好…

12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路

文章目录Java反射机制理解Class类获取Class类实例类的加载过程类加载器ClassLoader创建运行时类的对象获取运行时类的结构调用运行时类的指定结构动态代理Java反射机制 Reflection是被视为动态语言的关键&#xff0c;反射机制允许程序在执行期借助于Reflection API取得任何类的…

坚实原则:Liskov替代原则

以前&#xff0c;我们深入研究了坚实的原则&#xff0c;包括单一责任和开放/封闭原则。 Liskov替代原则&#xff08;LSP&#xff09;是子类型关系的一种特殊定义&#xff0c;称为&#xff08;强&#xff09;行为子类型&#xff0c; 假设对象S是对象T的子类型&#xff0c;则可…