栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

用简洁的语言详细讲解Java泛型;结合简单、清晰的Java代码示例,一看就懂,懂了就不会忘记(建议收藏)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用简洁的语言详细讲解Java泛型;结合简单、清晰的Java代码示例,一看就懂,懂了就不会忘记(建议收藏)

泛型概述 泛型程序设计

泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。——《百度百科》

Java泛型

Java 泛型的参数只可以代表类,不能代表个别对象。由于Java泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型,而且无法直接使用基本值类型作为泛型类型参数。——《百度百科》

使用泛型的好处
  • 编译期进行类型检查,消除运行期ClassCastException异常;
  • 消除了强制类型转换,减少不必要的代码。
泛型类型

在类/接口的定义中含有类型参数,类型参数在整个类/接口中有效。

泛型类(接口)

示例的泛型类中包含一个类型参数T,T可以接收任意引用变量类型。
泛型接口与泛型类相似。

public class GenericClass {
  private T t;

  public T getT() {
    return t;
  }

  public void setT(T t) {
    this.t = t;
  }

  public static void main(String[] args) {
    GenericClass genericString = new GenericClass<>();
    genericString.setT("a string");
    String resString = genericString.getT();
    System.out.println("泛型 , t is : " + resString);
    GenericClass genericInteger = new GenericClass<>();
    genericInteger.setT(1);
    // 自动拆箱
    int resInt = genericInteger.getT();
    System.out.println("泛型 , t is : " + resInt);
  }
}
泛型的命名规范

泛型类型使用单个大写字母命名,比如T。以下列出一些常用的类型参数:

  • E : Element (used extensively by the Java Collections framework)
  • K : Key
  • N : Number
  • T : Type
  • V : Value
  • S,U,V etc. : 2nd, 3rd, 4th types
多种类型参数

示例的类中含有2个类型参数K,V。

public class MyMap {
  private K k;
  private V v;

  public MyMap(K k, V v) {
    this.k = k;
    this.v = v;
  }

  public V getV(K k) {
    return v;
  }

  public static void main(String[] args) {
    MyMap myStringMap = new MyMap<>("key", "value");
    String vString = myStringMap.getV("key");
    System.out.println(vString);
    MyMap myIntMap = new MyMap<>(1, 1);
    // unboxing
    int vInt = myIntMap.getV(1);
    System.out.println(vInt);
  }
}
泛型方法

在方法的定义中含有类型参数,类型参数在整个方法中有效。
静态方法、非静态方法、构造方法中都允许含有类型参数。

public class GenericMethod {
  
  public  T nonStaticGet(T t) {
    return t;
  }

  
  public static  T staticGet(T t) {
    return t;
  }

  
  public  String put(K key, V value) {
    // 存储key、value...
    return "key : " + key + " , value : " + value;
  }

  public static void main(String[] args) {
    String str = GenericMethod.staticGet("static method!");
    System.out.println(str);
    GenericMethod gm = new GenericMethod();
    str = gm.nonStaticGet("non-static method!");
    System.out.println(str);
    str = gm.put(1, "one");
    System.out.println(String.format("Multiple Type Parameters! %s", str));
  }
}
有界类型参数
  • 使用类型参数T时,对传入的参数是没有任何限制;我们可以使用extends关键字实现对类型参数的限制,比如:T extends Number,T只允许传入数字类型的参数;extends关键字后面可以是类或者接口;
  • extends后面可以有多个类型限制,比如:。注意如果A、B、C中有一个是类,则类必须被放置在第一个位置,如例子中的A。
public class BoundedTypeParameters {
  public static  void print(T t) {
    System.out.println("The number is " + t);
  }

  public  void multipleBounds(T t) {
    
  }

  
  //  public  void multipleBounds1(T t) {}

  public static void main(String[] args) {
    BoundedTypeParameters.print(1);
    BoundedTypeParameters.print(1.1D);
    // 编译错误
    //    BoundedTypeParameters.print("1");
  }

  class A {
    
  }

  interface B {
    
  }

  interface C {
    
  }
}
通配符

通配符表示未知类型,在泛型中用?表示通配符,例如:List

上界通配符

使用extends关键字,例如,类型参数只能是Number本身或Number的子类。

下届通配符

使用super关键字,例如,类型参数只能是Integer本身或Integer的父类。

public class Wildcards {
  
  public void print(List list) {
    for (Object o : list) {
      System.out.print(o + " ");
    }
    System.out.println();
  }

  public void printUpperBounded(List list) {
    for (Object o : list) {
      System.out.print(o + " ");
    }
    System.out.println();
  }

  public void printLowerBounded(List list) {
    for (Object o : list) {
      System.out.print(o + " ");
    }
    System.out.println();
  }

  public static void main(String[] args) {
    Wildcards wildcards = new Wildcards();
    List intList = Arrays.asList(1, 2);
    wildcards.print(intList);
    wildcards.printUpperBounded(intList);
    List strList = Arrays.asList("1", "2");
    // 编译出错,类型参数只能是Number本身或Number的子类,如:List
    // wildcards.printUpperBounded(strList);
    List objList = Arrays.asList("Hello", "World!");
    wildcards.printLowerBounded(objList);
    // 编译出错,类型参数只能是Integer本身或Integer的父类,如:List
    // wildcards.printLowerBounded(strList);
  }
}


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号