JAVA泛型知识点

JAVA泛型


1.概述

泛型:即“参数化类型”。将类型由原来的具体类型参数化,类似于方法中的变量参数,此时类型同样定义为参数形式,只有在调用/运行时才传入具体的类型。

泛型的本质:为了参数化类型,即在不创建新的类型的情况下,通过反省制定的不同类型来控制形参具体显限制的类型,也就是说在使用泛型的过程中,操作的数据类型被指定为某一参数时,改类型可以用在泛型类、泛型接口、泛型方法中。

2.特性

泛型只在编译阶段有效--->由于JVM的泛型类型擦除。

    List<String> l1 = new ArrayList<String>();
    List<Integer> l2 = new ArrayList<Integer>();

    /*输出结果为true*/
    System.out.println(l1.getClass() == l2.getClass());

在编译过程中,验证泛型的类型正确性之后,将相关信息擦除。即泛型类型在编译阶段看似多个不同的类型,实际在编译之后的阶段,都是相同的基本类型。

3.泛型的使用

  • 泛型类
  • 泛型接口
  • 泛型方法

3.1 泛型类

通过泛型可以完成对一组类的操作对外开放相同的接口,典型有各种容器类:List、Set、Map等。

泛型类的基本写法:

    class 类名 <泛型标识>{
      /*该处T(泛型标识)由外部制定*/
      private 泛型标识 成员变量名;

      /**
      *@param 自定义
      *@return 返回泛型标识类型的类型
      */
      public 泛型标识 成员变量名(@param T t){}
    }


泛型标识:可以写为任意标识,常见的如T、E、K、V。
实例化泛型类时,必须制定T的具体类型(包括自定义类),不能使简单类型(如int、double)。

3.2 泛型接口

泛型接口常被用在各种类的生产器中。

泛型接口的基本写法:

    public interface 接口名<泛型标识/*这里用T*/>{
      public T 方法名();
    }

    /**
     *未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
     *如不声明,编译器报错:"Unknown class"
     */
    class ImplGenerator<T> implements Generator<T>{
      @override
      public T next(){
        return null;
      }
    }

3.3 泛型通配符

如:

    public void showKetValue(Geberic<?> obj){
                Log.d("泛型测试","key value is " + obj.getKey());
    }


类型通配符一般是使用?代替具体的类型实参。和Integer、String一样都是一种实际的类型。

使用场景:可以解决当具体类型不确定的时候,这个通配符就是?;当操作类型时,不需要使用类型的具体功能时,只是用Object类中的功能,那么可以用?通配符来表示未知类型。

3.4 泛型方法

大多数泛型类中的成员方法也是用了泛型,甚至有的泛型类中包含着泛型方法,学习时要注意区分。

泛型类:在实例化类的时候指明泛型的具体类型;泛型方法:在调用方法的时候指明泛型的具体类型。
泛型方法可出现在任意地方和任意场景中使用。

泛型方法的基本写法:

    /**
     *@param t 传入泛型实参
     *@return T 返回类型为T
     *说明:
     *1)只有声明了public和返回类型中间的<T>才是泛型方法
     *2)<T>表示四该方法将使用的泛型类型为T,诸如T、E、K等,该T可出现在泛型方法任意位置
     *3)Class<T>中的T表示为该类的泛型类型
     *4)泛型的数量也可以为任意多个
     *如:
     *public <T,K> K showKeyName(Generic<T> container){...}
     */
     public <T> genericMethod(Class<T> t) throws InstantiationException,
      IllegalAccessExceotion{
        T instance = t.newInstance();
        return instance;
      }

3.4.1 泛型方法与可变函数

如:

    public <T> void printMsg(T...args){
      for(T t:args){
        Log.d("Test"," t is " + t);
      }
    }

3.4.2 静态方法与泛型

类中的静态方法使用泛型:静态方法无法访问类上定义的泛型,方法操作的引用数据类型不确定的时候,必须要将泛型定义在该静态方法上

如:

    public class StaticGenerator<T> {
    ....
    /**
     *如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
     *即使静态方法要使用泛型类中已经声明过的泛型也不可以。
     *如:public static void show(T t){..},此时编译器会提示错误信息:
          "StaticGenerator cannot be refrenced from static context"
     */
    public static <T> void show(T t){}
    }

3.4.3 泛型方法总结

泛型方法可独立于类产生变化,基本原则如下:

无论何时,如果能做到,就尽量使用泛型方法,也就是说,如果使用泛型方法将整个类泛型化,那么就应该使用泛型方法。另外,对于一个static的方法,无法访问泛型类型的参数。所以如果要事static方法使用泛型能力,就必须使其成为泛型方法。

4. 泛型的上下边界

  • 添加上边界,即传入的类型实参必须是指定参数或其子类型

    public void showKeyValue(Generic<? extends Number> obj){}
  • 添加下边界,即传入的类型实参必须是制定参数或其父类
    public void showKeyValue(Generic<? super Integer> obj){}
  • 无边界,即通配符?,参看"3.3泛型通配符"

例子:

    //在泛型方法中添加上下边界限制的时候,必须在权限声明与返回值之间的<T>上添加上下边界,即在泛型声明的时候添加
    //public <T> T showKeyName(Generic<T extends Number> container),编译器会报错:"Unexpected bound"
    public <T extends Number> T showKeyName(Generic<T> container){
      System.out.println("container key :" + container.getKey());
      T test = container.getKey();
      return test;
    }

:泛型的上下边界添加,必须与泛型的声明在一起

原文地址:http://blog.51cto.com/13801495/2130175

时间: 2024-12-19 12:31:16

JAVA泛型知识点的相关文章

Java泛型知识点:泛型类、泛型接口和泛型方法

有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一.先来看一个没有泛型的情况下的容器类如何定义: public class Container { private String key; private String value; public Container(String k, String v) { key = k; value = v; } public String getKey() { return key; }

Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是CountDownLatch? 倒计时计数器,调用CountDownLatch对象的CountDown()方法就将计数器减一,当计数到达0时,则所有等待者或者全部等待者开始执行. 2.如何用? new CountDownLatch(1); 直接new,其构造函数必须传一个int类型的参数,参数的意思是: c

从零开始自学Java泛型的设计难不难?

引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用.本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除. 泛型基础 泛型类 我们首先定义一个简单的Box类: public class Box { private String object; public void set(String object) { this.object = object; } public String get() { return object;

Java泛型详解(转)

文章转自  importNew:Java 泛型详解 引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用.本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除. 泛型基础 泛型类 我们首先定义一个简单的Box类: public class Box { private String object; public void set(String object) { this.object = object; } public Stri

Java 泛型、通配符? 解惑

Java 泛型通配符?解惑 分类: JAVA 2014-05-05 15:53 2799人阅读 评论(4) 收藏 举报 泛型通配符上界下界无界 目录(?)[+] 转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T 有类型 ? 未知类型 一.通配符的上界 既然知道List<Cat>并不是List<Anilmal>的子类型,那就需要去寻找替他解决的办法, 是AnimalTrianer.act()方法变得更为通用(既可以接受List&

JAVA基础知识点总结(全集)

1.JAVA简介 1.1java体系结构:j2se,javaweb,j2ee 1.2java特点:平台无关(虚拟机),垃圾回收(使得java更加稳定) 1.3 JDK与JRE,JDK:java开发环境,JRE:java运行环境 1.4第一个java程序:HelloWorld,java的入口是main(public static void main(String[] args)) 1.5java程序的开发步骤:.java编译(javac)成.class运行(java).class文件 2.基本数据

Java基础11:Java泛型详解

Java基础11:Java泛型详解 泛型概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参). 泛型的本质是为了参数化类型(在不创建新的类型的

java泛型常见面试题

背景:泛型这个知识点平时用的不多,但是在面试的时候很容就被问到,所以还是要准备一些基础的知识储备. 面试旧敌之 Java 泛型 :主要概念及特点 “泛型” 意味着编写的代码可以被不同类型的对象所重用. 泛型是在JDK1.5之后出现的. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 可以看到,使用 Object 来实现通用.不同类型的处理,有这么两个缺点: 每次使用时都需要强制转换成想要的类型 在编译时编译器并不知道类型转换是否正常,运行时才知道,不安全 根据<Java 编程

第11讲-Java泛型和文件操作

1.知识点 1.1.课程回顾 1.2.本章重点 1.2.1.泛型 1.2.2.文件操作 2.具体内容 2.1.Java泛型 2.1.1.为什么需要泛型 我们发现在List中,底层是Object[ ]数组,那么也就是说,List可以存储任意对象类型.但是在实际开发中,我们一般一个List只存储一种类型,所以LIst就无法保证数据类型的约束. 第二点,我们存储的假如是String,那么我们希望取出来的数据类型也是String,没有泛型的时候,无论存什么,取出来的数据类型都是Object.我们希望存什