理解Java泛型 通配符 ? 以及其使用

什么是泛型:

泛型从字面上理解,是指一个类、接口或方法支持多种类型,使之广泛化、一般化和更加通用。Java中使用Object类来定义类型也 能实现泛型,但缺点是造成原类型信息的丢失,在使用中容易造成ClassCastException。

Java泛型带到的好处:

  1. 使得一个类或方法中的类型参数化,最终达到代码复用的效果。( 不使用泛型,你可能需要每种情况的类或方法都要定义一遍 )
  2. 实现类型检查的功能,避免ClassCastException。(这是相对于使用Object类型实现泛型而言。因为我可以每个类都定义一遍来实现所谓的类型检查。)

泛型自定义:类、接口、方法

//定义泛型类,接口的定义和类一样
class G1<T> {
    T content;
}

// 定义泛型方法,方法的头部使用<T>声明,注意结构
class GMethod1 {

    // 一般泛型方法定义
    public static <T> void method1(T params) {

    }

    // 返回值也为泛型
    public static <E> E method2(E params) {
        E content = params;
        return content;
    }

}

// extends 的使用,限定泛型的范围,等于或者是extends的子类
class G2<T extends Number> {
    T content;
}

泛型的使用

    //泛型类或接口的使用
    List<String> list = new ArrayList<>();

    //泛型方法的使用,在方法前面使用<>传入类型
    <String>gMethod1.method1("str");
    <Integer>gMethod1.method1(new Integer(1));

    //如果入参的参数中使用了T,则可以省略方法前面的<>,编译器可以自行识别出其类型
    gMethod1.method1("str");
    gMethod1.method1(new Integer(1));

通配符?

什么时候会用通配符:

通配符只有在修饰一个变量时会用到,使用它可方便地引用包含了多种类型的泛型;

    public static void main() {

        //不使用通配符
        ArrayList<Object> arr = new ArrayList<Object>();
        // ArrayList<Object> arr = new ArrayList<String>(); 编译不通过,arr只能引用包含Object的集合

        //使用通配符
        ArrayList<?> arr2;
        arr2 = new ArrayList<String>();
        arr2 = new ArrayList<Integer>();
        arr2.get(0);    //返回的,是一个Object对象,通配符会使原集合包含类型信息丢失,也是通配符的使用代价

    // 通常在方法参数中才会使用通配符,使得这个方法可以引用多种泛型集合。这个和范型方法不一样,这里只是一个引用变量
    void gMethod(ArrayList<? extends Number> param) {
    }

可以看到,通配符使用方便的同时,使原集合包含类型信息丢失。

通配符的extends super关键字

和定义泛型中的extend概念完全不一样,这里有它自己的含义

        ArrayList<? extends Number> arr3; // Number 是 Integer、Float的父类
        arr3 = new ArrayList<Integer>();
        arr3 = new ArrayList<Float>();
        // arr3 = new ArrayList<String>(); 编译不通过,String 和 Number不存在继承关系

        arr3.get(0);    //返回的,是一个Number对象
        arr3.add(null); //使用过通配符修饰的集合变量,只能add(null),因为这个集合中包含的类型已经确定,只是类型信息已经丢失了,add(Object)也不行

扩展:不使用泛型的变量和另一种方式

        //这样使用功能和通配符一样,可以多种引用,但一般不推荐这样使用
        ArrayList a4;
        a4 = new ArrayList<String>();
        a4 = new ArrayList<Integer>();
        a4.add(new Integer(1));
        a4.add(new String("str"));//和通配符引用不能add不一样,这样方式可以add多种类型元素,但一般不推荐

        a4.get(0);  //返回的,是一个Object对象
时间: 2024-11-07 21:06:12

理解Java泛型 通配符 ? 以及其使用的相关文章

Java泛型-- 通配符

转自:http://blog.csdn.net/flfna/article/details/6576394 ———————————————————————————————————————————— 通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: ◆ 向上造型一个泛型对象的引用 ◆ 向下造型一个泛型对象的引用 向上造型一个泛型对象的引用 例如,假设我们有很多箱子,每个箱子里都装有不同的水果,我们需要找到一种方法能够通用的处

Java泛型通配符学习 —— Java Generic&#39;s Wildcards

Java Generic's wildcards is a mechanism in Java Generics aimed at making it possible to cast a collection of a certain class, e.g A, to a collection of a subclass or superclass of A. This text explains how. 理解:Java的泛型通配符机制旨在实现集合的类型转换.例如集合A,转换为A的子类集合或

JAVA泛型通配符T,E,K,V区别,网友回复:一文秒懂

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

java泛型通配符?

转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T  有类型 ?  未知类型 一.通配符的上界 既然知道List<Cat>并不是List<Anilmal>的子类型,那就需要去寻找替他解决的办法, 是AnimalTrianer.act()方法变得更为通用(既可以接受List<Animal>类型,也可以接受List<Cat>等参数).在java里解决办法就是使用通配符"?",具体到Anim

深入理解java泛型

一. 什么是泛型? 泛 型(Generic type 或者 generics)是对 简单的理解,就是对类型的参数化,比如我们定义一个类属性或者实例属性时,往往要指定具体的类型,如Integer.Person等等, 但是如果使用了泛型,我们把这些具体的类型参数化,用一个广泛的可以表示所有类型的"类型"T来定义,那这个T就是泛型的表示. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给

JAVA泛型通配符T,E,K,V区别,T以及Class&lt;T&gt;,Class&lt;?&gt;的区别

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

Java泛型 通配符? extends与super

本文来源:https://i.cnblogs.com/EditPosts.aspx?opt=1 感谢博主.本文仅供参考学习. Java 泛型 关键字说明 ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object extends 示例 static class Food{} static class Frui

JAVA 泛型通配符 ? EXTENDS SUPER 的用法

1. <? extends Hero> ArrayList heroList<? extends Hero> 表示这是一个Hero泛型或者其子类泛型heroList 的泛型可能是HeroheroList 的泛型可能是APHeroheroList 的泛型可能是ADHero所以 可以确凿的是,从heroList取出来的对象,一定是可以转型成Hero的 但是,不能往里面放东西,因为放APHero就不满足<ADHero>放ADHero又不满足<APHero> 2.

java 泛型通配符 extends, super

引自:http://sharewind.iteye.com/blog/1622164 关键字说明 ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object extends 示例 static class Food{} static class Fruit extends Food{} static clas