①为什么要使用泛型通配符
请参考这篇随笔的下半部分 https://www.cnblogs.com/baxianhua/p/9194369.html
 
②通配符上限和通配符下限的简单解释
<? extends T>上限通配,表示?是T的一个未知子类。
<? super T>下限通配,表示?是T的一个未知父类。
 

  下面来分别讲一下

③.1<? extends T> 上限通配

这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的子类

举个例子
我们有一个水果类

/**
* 水果类
*/
public abstract class Fruit {
public abstract void eat();
}

然后创建两种水果继承水果类Fruit

/**
* 苹果类
*/
public class Apple extends Fruit {
@Override
public void eat() {
System.out.println("我是苹果,我是酸酸甜甜的");
}
}

/**
* 香蕉类
*/
public class Banana extends Fruit {
@Override
public void eat() {
System.out.println("我是香蕉,我是软软的");
}
}

我们还需要一个吃瓜群众

/**
* 吃瓜群众
*/
public class People<T extends Fruit> {
public void eatFruit(T t){
t.eat();
}
}

请注意定义People类的时候我们使用了泛型上限表示<T extends Fruit>
我们创建一个类测试一下

public class Test {
public static void main(String[] args) {
People<Apple> p1 = new People<>();
p1.eatFruit(new Apple()); People<Banana> p2 = new People<>();
p2.eatFruit(new Banana());
}
}

若此时我们创建一个橙子类,但不继承自Fruit父类

/**
* 橙子类
*/
public class Orange {
public void eat() {
System.out.println("我是橙子,我是酸酸的");
}
}

编译时期就会报错,提示Orange不在范围内,应该要继承Fruit类

编译报错

③.2<? extends T> 上限通配

表示只能接收Number这个类以及这个类的子类的数据类型。(extends表继承,就是这个类下面的东西)再举个例子如下

public static void function(Student<? extends Number> s){
System.out.println("姓名是:"+s.getName());
}

④.1<? super T> 下限通配

这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的父类。

例如

public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}

这里表示我们调用这个方法时可以传入参数是Integer或者Integer的父类,例如:

public class TestLowerBounded {
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
} public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
addNumbers(list1); List<Number> list2 = new ArrayList<>();
addNumbers(list2); List<Object> list3 = new ArrayList<>();
addNumbers(list3); List<String> list4 = new ArrayList<>();
//编译错误,因为String不是Integer的父类
//addNumbers(list4);
}
}

Number和Object都是Integer的父类,所以编译通过,而String不是Integer的父类,编译报错。

④.2<? super T> 下限通配

表示只能接收Number这个类以及这个类的父类的数据类型。(super表父类,超过这个类的东西)再举个例子如下

public static void function(Student<? super Number> s){
System.out.println("姓名是:"+s.getName());
}

以上就是泛型上限通配符和下限通配符的作用了,知识点比较小,希望可以一点一点积累,和大家一起进步。

Java 泛型通配符上限和通配符下限的更多相关文章

  1. JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)

    一.通配符上限和通配符下限接受的类型 通配符上限:<? extends T> 通配符下限:<? super T> 以下代码是测试结果,注释为解释说明 package xayd. ...

  2. Java泛型解析(02):通配符限定

    Java泛型解析(02):通配符限定      考虑一个这种场景.计算数组中的最大元素. [code01] public class ArrayUtil { public static <T&g ...

  3. java 泛型的上限与下限

    设置泛型对象的上限使用extends,表示参数类型只能是该类型或该类型的子类: 声明对象:类名<? extends 类> 对象名 定义类:类名<泛型标签 extends 类>{ ...

  4. Java泛型之上、下界通配符的理解(适合初学)

    泛型的由来 为什么需要泛型   Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的clas ...

  5. Java泛型学习笔记 - (七)浅析泛型中通配符的使用

    一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...

  6. Java泛型及实践

    代码及说明: package com.zsm.crazyjava; import java.util.ArrayList; import java.util.Collection; import ja ...

  7. Java泛型解析(03):虚拟机运行泛型代码

    Java泛型解析(03):虚拟机运行泛型代码      Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...

  8. java 泛型基础问题汇总

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引 ...

  9. Java泛型解析(04):约束和局限性

    Java泛型解析(04):约束和局限性           前两节.认识和学习了泛型的限定以及通配符.刚開始学习的人可能须要一些时间去体会到泛型程序设计的优点和力量,特别是想成为库程序猿的同学就须要下 ...

随机推荐

  1. vertical-align负值和margin-bottom负值的区别

    先看一下vertical-align在W3C当中的值有哪一些: 可是它有数值这一说确实很少提起,我们来看这么一段代码: <!DOCTYPE html> <html lang=&quo ...

  2. 【PHP】算法: 获取满足给定值的最优组合

    PHP 获取给定值的最优组合 方法 -   (蓝洛提供,博客地址: www.zhaorui.info) <?php ini_set('error_reporting','E_ALL^E_NOTI ...

  3. 使用Sublime Text 3做Python开发

    引言 刚转到OS X平台时,寻找写Python,JavaScript,Markdown等文件的工具时,比较了许多工具, 最终选择了Sublime Text 2,主要原因是其跨平台, 想着以后再转到wi ...

  4. executeQuery、executeUpdate 和 execute

    Statement 接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语句所产生的内容决定. 1. Resul ...

  5. sencha touch 入门系列 (三)sencha touch 项目创建

    通过上一章节的学习,我们的开发环境已经配置好了,接下来我们开始创建第一个sencha touch的项目,网络上很多sencha touch的教程都是手动搭建项目的, 不过手动搭建的项目缺少一些senc ...

  6. 单用户模式进入centos

    修改root密码----------------单用户模式操作 个人原创博客,转载请注明,否则追究法律责任 author: headsen chen date: 2017-9-30 1,开机后,迅速按 ...

  7. 【BZOJ4452】[Cerc2015]Export Estimate 并查集

    [BZOJ4452][Cerc2015]Export Estimate Description 给你一个n个点m条边的无向图,每条边有权值,我们可以选择一个整数lim来生成一个新的图,过程如下:  1 ...

  8. 查询hadoop参数变量

    [hadoop@master hadoop]$ hive -S -e 'set -v'|grep querylog|grep -E -v 'CLASSPATH|class'hive.querylog. ...

  9. UPDATE从左向右,变量优先,逐行更新.顺序执行的,可以交换两列之间的值

    CREATE TABLE tab_update (id TINYINT,n1 NVARCHAR(30),v1 NVARCHAR(30),s1 NVARCHAR(30)) INSERT INTO tab ...

  10. 关于string的length

    在C++里面,std::string的length()返回的是字节数,与编码方式有关. int main() { std::string s = "我是中国人"; std::cou ...