美文网首页
java泛型

java泛型

作者: 荡轻风 | 来源:发表于2017-09-14 17:16 被阅读0次

泛型类

一个泛型类 (generic class) 就是具有一个或多个类型变量的类。

  • 泛型类可以有多个类型变量。 例如 , 可以定义 Pair 类 , 其中第一个域和第二个域使用不同的类型,类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。
public class a<T,U>{}

泛型方法

当某个类只有一个方法需要使用泛型时,可不必将整个类声明为泛型类,可以单独声明泛型方法。

  • 泛型方法可以定义在普通类中, 也可以定义在泛型类中。
  • 当调用一个泛型方法时,在方法名前的尖括号中放人具体的类型。
public class ArrayAlg{
    public static <T> T getMiddle(T... a){
        return a[a.length / 2];
    }
}
String middle = ArrayAlg.<String>getMiddle("a","b","c");
//等同于,编译器有足够的信息能够推断出所调用的方法
String middle = ArrayAlg.getMiddle("a","b","c")

类型变量的限定

限定表示对变量进行进一步限制,必须继承自某类或者实现某接口。

  • <T extends BoundingType〉示 T 应该是绑定类型的子类型 (subtype) 。T 和绑定类型可以是类, 也可以是接口 。 选择关键字 extends 的原因是更接近子类的概念。
  • 一个类型变量或通配符可以有多个限定,限定类型用 “ & ” 分隔, 而逗号用来分隔类型变量,有个限定多个接口,但同时只能限定一个类,如果包含类时,需要将类作为第一位。
public static <A extends Comparable,B extends Comparable> void test(A a,B b){}

类型擦除

无论何时定义一个泛型类型,都自动提供了一个相应的原始类型(raw type) 。原始类型的名字就是删去类型参数后的泛型类型名。 擦除类型变M , 并替换为限定类型(无限定的变量用Object)

public class A<T>{
    private T a;
    private T b;
}
//由于T是“无限定变量”擦除后将转变成原始类型(Object)
public class B{
    private Object a;
    private Object b;
}
  • 原始类型用第一个限定的类型变量来替换 , 如果没有给定限定就用 Object 替换。
public class A<T extends Comparable & Serializable> implements Serializable{
    private T a; 
    private T b;
}
//将转化为
public class A implements Serializable{
    private Comparable a; 
    private Comparable b;
}
  • 当程序调用泛型方法时, 如果擦除返回类型 ,编译器插入强制类型转换。
Pair<Employee> buddies = ...;
Employee buddy = buddies.getFirst();
//编译器把这个方法调用翻译为两条虚拟机指令
//对原始方法 Pair.getFirst()的调用,此时泛型方法将返回Object
//将返回的Object类型强制转换为Employee类型。
  • 虚拟机对当get或set一个泛型字段时也会插人强制类型转换。

  • 桥方法

    在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。

public class a<T>{
    private T name;
    public void setName(T name){}
    public T getName(){}
}
//类型擦除后转变为
public class a{
    private Object name;
    public void setName(Object name){}
    public Object getName(){}
}

public class b extends a<String>{
    public void setName(String name){}
    public String getName(){}
}
//类型擦除后转变为 重载了setName方法而不是重写
public class b extends a{
    public void setName(String name){}
    //编译器会生成一个桥方法来实现多态
    public void setName(Object name){
        setName(String(name));
    }
    //编译器会生成一个桥方法实现对getName的覆盖
    public Object getName(){
        return String(this.name);
    }
}

  • 虚拟机中没有泛型 , 只有普通的类和方法 。
    所有的类型参数都用它们的限定类型替换 。
    桥方法被合成来保持多态 。
    为保持类型安全性 , 必要时插人强制类型转换

相关文章

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • java泛型中类型擦除的一些思考

    java泛型 java泛型介绍 java泛型的参数只可以代表类,不能代表个别对象。由于java泛型的类型参数之实际...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • JAVA 核心笔记 || [xxx] 泛型

    泛型 JAVA 的参数化类型 称为 泛型 泛型类的设计 Learn12.java 运行

  • 简单回顾Java泛型之-入门介绍

    什么时候开始有了Java泛型?什么是Java泛型?为什么要引入Java泛型?什么时候用到了泛型?可不可以给泛型下一...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • JAVA-泛型

    JAVA-泛型 sschrodinger 2018/11/15 简介 泛型是Java SE 1.5的新特性,泛型的...

网友评论

      本文标题:java泛型

      本文链接:https://www.haomeiwen.com/subject/vcwdsxtx.html