java泛型

author author     2023-05-12     304

关键词:

import java.util.*;
public class Example
public void addStrings(List<? super String> list)
list.add("foo");
list.add("bar");



第三行为什么用? super String 而不用? extends String

java泛型是1.5引进的一个新概念.
本题对于"? super T"和"? extends T",我从书上摘个经典的例子给你看看,如果不能理解,那么你就参考以下书籍慢慢体会,循序渐进!

"? super T"和"? extends T",都是java泛型通配符,而用法又有区别,
还有super 和extends 不是java类关系中的超类和继承的意思,他是通配符的下限和上限限制.

下面看一个通配符得高级用法:
在这一部分,我们来考虑一些通配符得高级用法。我们已经看到了上限通配符在从一个数据结构中进行读取的几个例子。现在考虑相反的情况,一个只写的数据结构。

接口Sink是这种情况的一个简单例子。

interface Sink<T>

void flush(T t);



我们可以想象他被如下面的代码一样使用。方法writeAll() 被设计来把集合coll的所有元素flush到sink snk,并且返回最后一个flush的元素。

public static <T> T writeAll(Collection<T> coll, Sink<T> snk)

T last = null;

for (T t : coll)

last = t;

snk.flush(last);



return last;



Sink<Object> s;

Collection<String> cs;

String str = writeAll(cs, s); // 非法的调用!!

像上面所写,writeAll() 的调用是非法的,因为没有有效的类型参数可以被推断出来。String 或 Object都不是T的合适的类型,因为Collection的元素和 Sink的元素必须是同样的类型。

我们可以解决这个问题,通过使用通配符来修改writeAll()的方法签名,如下:

<T> T writeAll(Collection<? extends T> coll, Sink<T> snk) …

String str = writeAll(cs, s); //可以调用但是返回值类型错误

这个调用现在是合法的,但是赋值产生错误,因为推断出的返回值类型是 Object因为T 匹配了Sink的类型,Object。

解决方案是使用一种我们还没有见过的有限制的通配符:有下限的通配符。语法 ? super T 表示T的一个未知的父类(或者是T自己)。这跟我们用? extends T 表示T的一个未知的子类是对应的。

<T> T writeAll(Collection<T> coll, Sink<? super T> snk) …

String str = writeAll(cs, s); // YES!!!

使用这个语法,这个调用是合法的,推断出来的T是String,正是我们想要的。

现在让我们看一个更现实的例子。一个 java.util.TreeSet<E> 代表一个有序的元素是E类型的树。创建一个TreeSet的一个方法是传递一个 Comparator 对象给构造函数。这个Comparator将会用来按照需要对TreeSet进行排序。

TreeSet(Comparator<E> c)

Comparator 接口是核心:

interface Comparator<T> int compare(T fst, T snd);

假定我们要创建一个 TreeSet<String> 并传递一个合适的 Comparator,我们需要传一个能比较String的Comparator。这可以是一个 Comparator<String>,也可以是一个 Comparator<Object>。然而我们不能用Comparator<Object>来调用上面的构造函数。我们可以使用一个有下限的通配符来得到我们需要的灵活性:

TreeSet(Comparator<? super E> c)

这允许任何可用的Comparator被传递进去。

作为使用下限通配符最终的例子,让我们来看看方法 Collections.max(),它返回一个集合中的最大的元素。

现在,为了让max()能工作,传进来的集合中的所有元素必须实现 Comparatable接口。而且,他们必须都能够被彼此比较(all be comparable to each other)。第一个尝试是:

public static <T extends Comparable<T>> T max(Collection<T> coll)

就是说,方法的参数是某一个能和自己进行比较的T的集合。这限制太严格了。

为什么?考虑一个能和任何对象进行比较的类型:

class Foo implements Comparable<Object> ... ...

Collection<Foo> cf = ...;

Collections.max(cf); // 应该能工作

cf 中的每个元素都可以和每个cf中的其他元素进行比较,因为每个这样的元素都是一个Foo,它可以和任意的对象进行比较,也可以和另一个Foo进行比较。

但是,使用上面的方法签名,我们发现这个调用被拒绝。推断出来的类型必须是Foo,但是Foo没有实现接口 Comparable<Foo>。

T 精确的(exactly)和自己能比较是不需要的。所需要的是 T能够和它的父类中的一个进行比较,这导出:(注:Collections.max()的实际方法签名更复杂,我们在第10部分再讨论。)

public static <T extends Comparable<? super T>> T max(Collection<T> coll)

这个推论对大多数想让 Comparable 对任意类型生效的用法中都有效:你总是应该使用 Comparable<? super T>。

总之,如果你有一个只使用类型参数T作为参数的API,它的使用应该利用下限通配符( ? super T )的好处。相反的,如果API只返回T,你应该使用上限通配符( ? extends T )来给你的客户端更大的灵活性。

(原文:This reasoning applies to almost any usage of Comparable that is intended to work for arbitrary types: You always want to use Comparable<? super T>.

In general, if you have an API that only uses a type parameter T as an argument, its uses should take advantage of lower bounded wildcards (? super T). Conversely, if the API only returns T, you'll give your clients more flexibility by using upper bounded wildcards (? extends T). )。

如果你想比较深刻的了解java泛型那么
建议你看看<Java1.5泛型指南>
中文链接地址:http://blog.csdn.net/explorers/archive/2005/08/15/454837.aspx#_Toc111865968
英文pdf格式地址:http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
参考技术A super是用来调用父类的方法和属性的不能用到方法的参数里面
,extends是用来实现继承的,第三行当然不能用super了要用extends了
参考技术B super 和extends都是继承的意思
super用于继承父类的方法
extends用于继承类
泛型就是强行转化的意思
不知道能不能帮到你
参考技术C 编译能通过,不过不理解啊!
我试了一下好像和List<String>没什么区别啊 !
参考技术D 应该就是? extends String吧,我没见过? super String,编译难道能通过?

java_泛型笔记(代码片段)

文章目录Java_泛型简介Java_泛型的概念Java_为什么存在泛型Java_自定义泛型结构Java_泛型的声明Java_泛型的实例化Java_泛型类Java_泛型方法Java_泛型在继承上的体现Java_通配符的使用Java_泛型简介集合容器类在设计阶段/声明阶段不能确... 查看详情

java泛型泛型简介(泛型类|泛型方法|静态方法的泛型|泛型类与泛型方法完整示例)(代码片段)

文章目录一、泛型简介二、泛型类三、泛型方法四、静态方法的泛型五、泛型类与泛型方法完整示例一、泛型简介泛型可以简单理解为参数化类型,主要作用在类,方法,接口上;java泛型与C++模板:Java中的泛型,是仿照C++中... 查看详情

java泛型与非泛型java(代码片段)

查看详情

java高级--java泛型

类型的参数化泛型类可以同时设置多个参数泛型类可以继承泛型类泛型类可以实现泛型接口示例--泛型类packagecom.date;publicclassGenericDemo{publicstaticvoidmain(String[]args){ GenClass<String>genClass=newGenClass<String>("tanlei"); System.out 查看详情

java泛型

1、什么是泛型Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许开发人员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。2、... 查看详情

java之泛型

1、为什么要有泛型Generic?2、总结Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不... 查看详情

java泛型是什么?一文带你吃透泛型(代码片段)

文章目录1.Java泛型2.泛型类3.泛型接口4.泛型方法5.泛型集合Java编程基础教程系列1.Java泛型Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。其主要的形式有泛型类,泛型接口和泛型方法。泛型概... 查看详情

java--泛型

泛型简而言之就是类型的参数化泛型分为泛型接口、泛型类和泛型方法,不存在泛型数组。举例//泛型类;publicclassData<T>{privateTdata;publicData(Tdata){this.data=data;}publicTgetData(){returndata;}}publicclassTest02{publicstaticvoidmain(String[]arg 查看详情

java泛型梳理

java泛型梳理概述泛型,即参数化类型,是在JDK1.5之后才开始引入的。所谓参数化类型是指所操作的数据类型在定义时被定义为一个参数,然后在使用时传入具体的类型。这种参数类型可以用在类,接口,方法的创建中,分别被... 查看详情

java泛型

Java泛型Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。假定我们有这... 查看详情

java----泛型

 自定义泛型:浮动  泛型只会在 查看详情

java-28java泛型

Java泛型如果我们只写一个排序方法,就能够对整型数组、字符串数组甚至支持排序的任何类型的数组进行排序,这该多好啊。Java泛型方法和泛型类支持程序员使用一个方法指定一组相关方法,或者使用一个类指定一组相关的类... 查看详情

java泛型

Java泛型如果我们只写一个排序方法,就能够对整形数组、字符串数组甚至支持排序的任何类型的数组进行排序,这该多好啊。Java泛型方法和泛型类支持程序员使用一个方法指定一组相关方法,或者使用一个类指定一组相关的类... 查看详情

java泛型

1/**2*泛型定义3*泛型是JavaSE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。Java语言引入泛型的好... 查看详情

java学习----泛型

目录  1.泛型的定义  2.泛型的使用  3.泛型通配符 一、泛型的定义  泛型是java5的新特性,使用泛型会让程序编写简单安全,在编译的时候就会检查类型是否安全  定义:所谓泛型就是允许在定义类、接口和方... 查看详情

java泛型

Java中的泛型,通常使用<E>来表示。泛型是指参数化类型。例如:  List<String>li=newArrayList<String>() 泛型是JavaSE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类... 查看详情

java泛型java使用泛型的意义

Java泛型Java使用泛型的意义@authorixenos  直接意义在编译时保证类型安全 根本意义a)类型安全问题源自可复用性代码的设计,泛型保证了类型安全的复用模板b)使用复用性模板时不用手动强制类型转换 三种泛型实现... 查看详情

java泛型

Java中的泛型(GenericType)基本精神:数据类型参数化集合框架中没使用泛型和使用泛型的比较没使用泛型ListmyIntList=newLinkedList();//1myIntList.add(newInteger(100));//2Integerx=(Integer)myIntList.iterator().next();//3  使用泛型List<Inte 查看详情