Java泛型初学者之上、下界通配符的深入理解

泛型的由来

为什么需要泛型

Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的class就会很稳定。但是假如说我不知道这个参数要传什么类型的,因为公司需求在变,如果写死的那就只能便以此需求就改一次,很麻烦。sun公司也注意到这个问题,这样会让代码的灵活性降低,他们就研究出了泛型。

泛型初识

什么是泛型,可以字面理解就是一个泛泛的类型,他是不确定的,在Java代码编译的时候用泛型是不会出错的,而在运行期时就会报错,说你这种第一是不合理的。这是为什么呢。因为为了提高灵活性,就在编译时期将条件放宽,但是泛型一定要在运行的时候告诉jvm你给我的数据到底是什么类型的,否则jvm会是懵逼的。所以泛型的好处就是将类型的灵活性提高,也只是在Java语法的基础上提高,不过泛型还是比较实用的。

何时使用泛型

泛型的应用场景就是应用在模型(可以理解为存储数据的盒子),我为了这个盒子适用更多的地方我就用将需要存入的数据用一个泛型表示,当然可以传入多值。如果是相同类型的对象就用一个泛型的数组比较好,学过集合的小伙伴应该都知道,没学过的那你应该补补课了。

泛型的语法

public class A<T extends B>{
 T t;
}

泛型的缺点或者为什么需要上、下边界

泛型的虽然强大,但是世界上任何东西东部是完美的。它也有缺陷。比如说我有一个盒子我想装苹果,但是我还可能想装香蕉那怎么办。那还不好说,在给一个参数不就行了,那十个呢,二十个呢。em....的确是。如果说我们想装的东西都属于一个类并且只要是这个类的子类就可以装。这个想法sun为我们想好了。那就是用上边界通配符。语法是 T是泛型,M是T的父类。我们就定义一个水果类(Fruit),盛装就容器就是盘子(Dish),现在我们就可以装任何水果了,不错吧!

上边界Java代码

public class Dish<T extends Fruit>{
 private T fruitChild;

 public Dish(T fruitChild){
 this.fruitChild = fruitChild;
 }

 public T getFruitChild(){
 return fruitChild;
 }

 public void setFruitChild(T f){
 this.fruitChild = f;
 }

 public static void main(String[] args){

 Dish dish = new Dish<apple>();
 Apple apple = new apple(); //apple must be Fruit child;
 dish.setFruitChild(apple);

 system.out.printf(dish.getFruitChild);
 }
}

下边界Java代码

public class Dish<T super Apple>{
 private T appleFather;

 public Dish(T appleFather){
 this.appleFather = appleFather;
 }

 public T getAppleFather(){
 return appleFather;
 }

 public void setAppleFather(T f){
 this.appleFather = f;
 }

 public static void main(String[] args){

 Dish dish = new Dish<Fruit>();
 Fruit fruit = new Fruit(); //fruit must be apple son;
 dish.setAppleFather(fruit);

 system.out.printf(dish.getAppleFather);
 }
}

什么是上边界通配符

当泛型T给定形如 的A类型到A类型任何子类的限制域,可以匹配任何在此限制域中的类型,此种表示叫上边界通配符。

上边界通配符理解

什么是下边界通配符

当泛型T给定形如 的A类型到A类型任何父类的限制域,可以匹配任何在此限制域中的类型,此种表示叫下边界通配符。

下边界通配符理解#

上下边界通配符的缺点

上界<? extends T>不能往里存,只能往外取。

解释

因为编译器只知道传入的是T的子类,但具体是哪一个编译器不知道,他只标注了一个占位符,当?传过来时,他不知道这能不能和占位符匹配,所以set不了。

下界<? super T>不影响往里存,但往外取只能放在Object对象里。

解释

因为下边界已经限制了?的粒度,他只可能是T本身或者是T的父类。我们想想,我想要一个T,你却返回给我一个比T小的Object,这样我们就因为精度损失而拿不到想要的数据了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • 详谈Java泛型中T和问号(通配符)的区别

    类型本来有:简单类型和复杂类型,引入泛型后把复杂类型分的更细了. 概述 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单. 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对

  • Java 泛型总结(三):通配符的使用

    简介 前两篇文章介绍了泛型的基本用法.类型擦除以及泛型数组.在泛型的使用中,还有个重要的东西叫通配符,本文介绍通配符的使用. 这个系列的另外两篇文章: Java 泛型总结(一):基本用法与类型擦除 Java 泛型总结(二):泛型与数组 数组的协变 在了解通配符之前,先来了解一下数组.Java 中的数组是协变的,什么意思?看下面的例子: class Fruit {} class Apple extends Fruit {} class Jonathan extends Apple {} class

  • java泛型常用通配符实例解析

    这篇文章主要介绍了java泛型常用通配符实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天在看ArrayList原码是看到这样的一个符号,好奇怪. ?表示通配符,表示的意思是匹配E或E的子类,具体类型未知. 1.限定通配符 编写一个类似于ArrayList的动态数据 public class Gys<T> { private final static int default_capacity =10; private int end

  • 一看就懂 详解JAVA泛型通配符T,E,K,V区别

    1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法.Java语言引入泛型的好处是安全简单. 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的.对于强制类型转

  • Java泛型之上界下界通配符详解

    泛型,继承和子类 如你所知,只要类型兼容,就可以将一种类型的对象分配给另一种类型的对象.例如,你可以指定一个整数一个对象,因为对象是一个整数的超类型: Object someObject = new Object(); Integer someInteger = new Integer(10); someObject = someInteger; // 好 在面向对象的术语中,这被称为"是一种"关系.由于Integer 是一种Object,因此允许赋值.但是Integer也是一种Num

  • Java泛型类型通配符和C#对比分析

    c#的泛型没有类型通配符,原因是.net的泛型是CLR支持的泛型,而Java的JVM并不支持泛型,只是语法糖,在编译器编译的时候都转换成object类型 类型通配符在java中表示的是泛型类型的父类 public void test(List<Object> c) { for(int i = 0;i < c.size();i++) { System.out.println(c.get(i)); } } //创建一个List<String>对象 List<String&g

  • 浅谈Java泛型通配符解决了泛型的许多诟病(如不能重载)

    泛型: package Java基础增强; import java.util.ArrayList; import java.util.List; import org.junit.Test; public class Test2 { @Test public void fun1(){ Object[] objects = new Object[10]; List list = new ArrayList(); String[] strings = new String[10]; List<Str

  • Java中泛型通配符的使用方法示例

    本文实例讲述了Java中泛型通配符的使用方法.分享给大家供大家参考,具体如下: 一 点睛 引入通配符可以在泛型实例化时更加灵活地控制,也可以在方法中控制方法的参数. 语法如下: 泛型类名<? extends T> 或 泛型类名<? super T> 或 泛型类名<?> ? extends T:表示T或T的子类 ? super T:表示T或T的父类 ?:表示可以是任意类型 二 通配符在泛型类创建泛型对象中使用 1 代码 class gent<T> { publ

  • Java泛型初学者之上、下界通配符的深入理解

    泛型的由来 为什么需要泛型 Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的class就会很稳定.但是假如说我不知道这个参数要传什么类型的,因为公司需求在变,如果写死的那就只能便以此需求就改一次,很麻烦.sun公司也注意到这个问题,这样会让代码的灵活性降低,他们就研究出了泛型. 泛型初识 什么是泛型,可以字面理解就是一个泛泛的类型,他是不确定的,在Java代码编译的时候用泛型是不会出错

  • java泛型通配符详解

    前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 泛型带来的好处 在没有泛型的情况的下,通过对类型 Object 的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的.对于强制类型转换错误的情况,编译器可能不提示错

  • Java基础之java泛型通配符详解

    前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 泛型带来的好处 在没有泛型的情况的下,通过对类型 Object 的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的.对于强制类型转换错误的情况,编译器可能不提示错

  • 最新Java 泛型中的通配符讲解

    目录 一.什么是类型擦除? 二.案例实体准备 三.常用的 ?, T, E, K, V, N的含义 四.上界通配符 < ? extends E> 五.下界通配符 < ? super E> 六.什么是PECS原则? 七.通过一个案例来理解 ?和 T 和 Object 的区别 本文内容如下: 1. 什么是类型擦除2.常用的 ?, T, E, K, V, N的含义3.上界通配符 < ?extends E>4.下界通配符 < ?super E>5.什么是PECS原则6

随机推荐