java 泛型的通配继承_Java泛型详解:Java泛型集合、泛型类、泛型方法、泛型的使用...

news/2024/7/8 5:46:16

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

泛型集合

泛型本质上是提供类型的“类型参数”,也就是参数化类型。我们可以为类、接口或方法指定一个类型参数,通过这个参数限制操作的数据类型,从而保证类型转换的绝对安全。

例 1

下面将结合泛型与集合编写一个案例实现图书信息输出。 (1) 首先需要创建一个表示图书的实体类 Book,其中包括的图书信息有图书编号、图书名称和价格。Book 类的具体代码如下:

public class Book{private int Id; //图书编号private String Name; //图书名称private int Price; //图书价格public Book(int id,String name,int price){ //构造方法this.Id=id;this.Name=name;this.Price=price;}public String toString(){ //重写 toString()方法return this.Id+", "+this.Name+","+this.Price;}}

(2) 使用 Book 作为类型创建 Map 和 List 两个泛型集合,然后向集合中添加图书元素,最后输出集合中的内容。具体代码如下:

import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Test14{public static void main(String[] args){//创建3个Book对象Book book1=new Book(1,"唐诗三百首",8);Book book2=new Book(2,"小星星",12);Book book3=new Book(3,"成语大全",22);Map books=new HashMap(); //定义泛型 Map 集合books.put(1001,book1); //将第一个 Book 对象存储到 Map 中books.put(1002,book2); //将第二个 Book 对象存储到 Map 中books.put(1003,book3); //将第三个 Book 对象存储到 Map 中System.out.println("泛型Map存储的图书信息如下:");for(Integer id:books.keySet()){//遍历键System.out.print(id+"——");System.out.println(books.get(id)); //不需要类型转换}List bookList=new ArrayList(); //定义泛型的 List 集合bookList.add(book1);bookList.add(book2);bookList.add(book3);System.out.println("泛型List存储的图书信息如下:");for(int i=0;i

在该示例中,代码“Map books=new HashMap();”创建了一个键类型为 Integer、值类型为 Book 的泛型集合,即指明了该 Map 集合中存放的键必须是 Integer 类型、值必须为 Book 类型,否则编译出错。在获取 Map 集合中的元素时,不需要将"books.get(id);"获取的值强制转换为 Book 类型,程序会隐式转换。在创建 List 集合时,同样使用了泛型,因此在获取集合中的元素时也不需要将“bookList.get(i)”代码强制转换为 Book 类型,程序会隐式转换。 执行结果如下:

泛型Map存储的图书信息如下:

1001——1, 唐诗三百首,8

1003——3, 成语大全,22

1002——2, 小星星,12

泛型List存储的图书信息如下:

1, 唐诗三百首,8

2, 小星星,12

3, 成语大全,22

泛型类

除了可以定义泛型集合之外,还可以直接限定泛型类的类型参数。语法格式如下:

public class class_name{}

其中,class_name 表示类的名称,data_ type1 等表示类型参数。Java 泛型支持声明一个以上的类型参数,只需要将类型用逗号隔开即可。 泛型类一般用于类中的属性类型不确定的情况下。在声明属性时,使用下面的语句:

private data_type1 property_name1;private data_type2 property_name2;

该语句中的 data_type1 与类声明中的 datajype1 表示的是同一种数据类型。

例 2

在实例化泛型类时,需要指明泛型类中的类型参数,并赋予泛型类属性相应类型的值。例如,下面的示例代码创建了一个表示学生的泛型类,该类中包括 3 个属性,分别是姓名、年龄和性别。

public class Stu{private N name; //姓名private A age; //年龄private S sex; //性别//创建类的构造函数public Stu(N name,A age,S sex){this.name=name;this.age=age;this.sex=sex;}//下面是上面3个属性的setter/getter方法public N getName(){return name;}public void setName(N name){this.name=name;}public A getAge(){return age;}public void setAge(A age){this.age = age;}public S getSex(){return sex;}public void setSex(S sex){this.sex=sex;}}

接着创建测试类。在测试类中调用 Stu 类的构造方法实例化 Stu 对象,并给该类中的 3 个属性赋予初始值,最终需要输出学生信息。测试类的代码实现如下:

public class Test14{public static void main(String[] args){Stu stu=new Stu("张晓玲",28,'女');String name=stu.getName();Integer age=stu.getAge();Character sex=stu.getSex();System.out.println("学生信息如下:");System.out.println("学生姓名:"+name+",年龄:"+age+",性别:"+sex);}}

该程序的运行结果如下:

学生信息如下:

学生姓名:张晓玲,年龄:28,性别:女

在该程序的 Stu 类中,定义了 3 个类型参数,分别使用 N、A 和 S 来代替,同时实现了这 3 个属性的 setter/getter 方法。在主类中,调用 Stu 类的构造函数创建了 Stu 类的对象,同时指定 3 个类型参数,分别为 String、Integer 和 Character。在获取学生姓名、年龄和性别时,不需要类型转换,程序隐式地将 Object 类型的数据转换为相应的数据类型。

泛型方法

到目前为止,我们所使用的泛型都是应用于整个类上。泛型同样可以在类中包含参数化的方法,而方法所在的类可以是泛型类,也可以不是泛型类。也就是说,是否拥有泛型方法,与其所在的类是不是泛型没有关系。 泛型方法使得该方法能够独立于类而产生变化。如果使用泛型方法可以取代类泛型化,那么就应该只使用泛型方法。另外,对一个 static 的方法而言,无法访问泛型类的类型参数。因此,如果 static 方法需要使用泛型能力,就必须使其成为泛型方法。 定义泛型方法的语法格式如下:

[访问权限修饰符][static][final]返回值类型方法名([形式参数列表])

例如:

public static List find(Classclass,int userId){}

一般来说编写 Java 泛型方法,其返回值类型至少有一个参数类型应该是泛型,而且类型应该是一致的,如果只有返回值类型或参数类型之一使用了泛型,那么这个泛型方法的使用就被限制了。下面就来定义一个泛型方法,具体介绍泛型方法的创建和使用。

例 3

使用泛型方法打印图书信息。定义泛型方法,参数类型使用“T”来代替。在方法的主体中打印出图书信息。代码的实现如下:

public class Test16{public static void List(T book){ //定义泛型方法if(book!=null){System.out.println(book);}}public static void main(String[] args){Book stu=new Book(1,"细学 Java 编程",28);List(stu); //调用泛型方法}}

该程序中的 Book 类为前面示例中使用到的 Book 类。在该程序中定义了一个名称为 List 的方法,该方法的返回值类型为 void,类型参数使用“T”来代替。在调用该泛型方法时,将一个 Book 对象作为参数传递到该方法中,相当于指明了该泛型方法的参数类型为 Book。 该程序的运行结果如下:

1, 细学 Java 编程,28

泛型的高级用法

泛型的用法非常灵活,除在集合、类和方法中使用外,本节将从三个方面介绍泛型的高级用法,包括限制泛型可用类型、使用类型通配符、继承泛型类和实现泛型接口。

1. 限制泛型可用类型

在 Java 中默认可以使用任何类型来实例化一个泛型类对象。当然也可以对泛型类实例的类型进行限制,语法格式如下:

class 类名称

其中,anyClass 指某个接口或类。使用泛型限制后,泛型类的类型必须实现或继承 anyClass 这个接口或类。无论 anyClass 是接口还是类,在进行泛型限制时都必须使用 extends 关键字。 例如,在下面的示例代码中创建了一个 ListClass 类,并对该类的类型限制为只能是实现 List 接口的类。

//限制ListClass的泛型类型必须实现List接口public class ListClass{public static void main(String[] args){//实例化使用ArrayList的泛型类ListClass,正确ListClass lc1=new ListClass();//实例化使用LinkedList的泛型类LlstClass,正确ListClass lc2=new ListClass();//实例化使用HashMap的泛型类ListClass,错误,因为HasMap没有实现List接口//ListClass lc3=new ListClass();}}

在上述代码中,定义 ListClass 类时设置泛型类型必须实现 List 接口。例如,ArrayList 和 LinkedList 都实现了 List 接口,所以可以实例化 ListClass 类。而 HashMap 没有实现 List 接口,所以在实例化 ListClass 类时会报错。 当没有使用 extends 关键字限制泛型类型时,其实是默认使用 Object 类作为泛型类型。因此,Object 类下的所有子类都可以实例化泛型类对象,如图 1 所示的这两种情况。

图1 两个等价的泛型类

2. 使用类型通配符

Java 中的泛型还支持使用类型通配符,它的作用是在创建一个泛型类对象时限制这个泛型类的类型必须实现或继承某个接口或类。 使用泛型类型通配符的语法格式如下:

泛型类名称 extends List>a=null;

其中,“ extends List>”作为一个整体表示类型未知,当需要使用泛型对象时,可以单独实例化。 例如,下面的示例代码演示了类型通配符的使用。

A extends List>a=null;a=new A (); //正确b=new A (); //正确c=new A (); //错误

在上述代码中,同样由于 HashMap 类没有实现 List 接口,所以在编译时会报错。

3. 继承泛型类和实现泛型接口

定义为泛型的类和接口也可以被继承和实现。例如下面的示例代码演示了如何继承泛型类。

public class FatherClass{}public class SonClass extents FatherClass{}

如果要在 SonClass 类继承 FatherClass 类时保留父类的泛型类型,需要在继承时指定,否则直接使用 extends FatherClass 语句进行继承操作,此时 T1、T2 和 T3 都会自动变为 Object,所以一般情况下都将父类的泛型类型保留。 下面的示例代码演示了如何在泛型中实现接口。

interface interface1{}interface SubClass implementsInterface1{}


http://www.niftyadmin.cn/n/2010279.html

相关文章

真是记忆力不行了,得,该记录记录,该书写书写。

就记录下想法,还要正文!!!转载于:https://blog.51cto.com/13435030/2104931

usb万能驱动win7_给 win7 系统镜像添加驱动

继上篇文章(win 10 重装 win 7 系统),这篇谈谈怎么制作自己的,安全的 win 7 镜像。一、给镜像添加驱动回归正题,制作自己的 win 7 镜像。我采用的是这个博主的办法:[ win7原版映像中添加usb3.0驱动 ]文章写…

一步之遥——第七届蓝桥杯C语言B组(国赛)第一题

原创 一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里。矿车停在平直的废弃的轨道上。他的面前是两个按钮,分别写着“F”和“B”。 小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。按F,会前进97米。按B会后…

java autoconfig_SpringBoot之AutoConfig自动配置

1. XxxxAuto在SpringBoot中有很多以XxxxAutoConfiguration注解,其实他的作用就是,自动配置当前模块要依赖的类例如:EnableAutoConfiguration就告诉SpringBoot需要加载那些类,spring-boot-1.5.1.RELEASE.jar/META-INF/spring.factories 在该文件中2. EnableSpringBoo…

@manytomany 保存后数据被删除_Smartbi V9数据挖掘完整介绍

Smartbi Mining平台是一个注重于实际生产应用的数据分析预测平台,它旨在为个人、团队和企业所做的决策提供预测。该平台不仅可为用户提供直观的流式建模、拖拽式操作和流程化、可视化的建模界面,还提供了大量的数据预处理操作。此外,它内置了…

php 如何跳转回前一个页面_PHP页面跳转到另一个页面的方法

PHP页面跳转到另一个页面的方法PHP页面跳转到另一个页面的方法是PHP学习当中必须掌握的,下面小编给大家整理了PHP页面跳转到另一个页面的方法,一起来学习吧!PHP页面跳转到另一个页面的方法一、用HTTP头信息也就是用PHP的header函数。PHP里的h…

js和php能生成一样的随机数_JS实现去重的随机数生成

这次给大家带来JS实现去重的随机数生成,JS实现去重随机数生成的注意事项有哪些,下面就是实战案例,一起来看一下。1.实验前准备:Math函数的理解数组方法的理解2.实验操作:随机数生成body{font-size: 20px;}#box{border:3px solid #…

uNo面板L灯一直闪_LED智能互联办公室照明恒流调光IC芯片无频闪H5114 - 信息发布 - 电子工程世界...

H5114 --【方案名称:LED智能互联办公室照明恒流调光IC芯片无频闪H5114】关键词:办公照明,无频闪,智能调光调色,智能照明,高辉度,65536:1调光比,共阳极,调光深…