博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java泛型总结
阅读量:772 次
发布时间:2019-03-24

本文共 2819 字,大约阅读时间需要 9 分钟。

一、概念解释

泛型类:

  • 引出:JDK1.5,为了解决程序中向下转型出现的参数转换安全问题
  • 解释:类在定义的时候不会设置属性或方法参数的具体类型,而是使用时定义
  • 基本语法:MyClass类就是一个泛型类
    class MyClass
    { T value;//T代表变量类型,可以是任意类型,与
    不同}

    <T>:T代表类型参数,可以指代任何引用类型这里指的是Object类可以接收的类型)

  • 常见参数类型:T(类)、E(元素)、K,V(键值对)

  • 作用:

  1. 用于检测编译期,参数类型设置问题,只有传入参数与使用定义类型一致时才可设置

  2. 杜绝向下转型带来的隐患

二、泛型方法

  • 语法
public 
T test(T t){ return t;}
  1. 第一个T:<T>,代表类型参数,不能省略,要写在第二个T之前
  2. 第二个T:代表方法的返回值类型
  3. 第三个T:代表方法参数的类型
  • 与泛型类共存
  1. 若泛型类与泛型方法共存,使用同一个类型参数,泛型类T与泛型方法T没有任何联系,泛型方法始终以自己定义的类型参数为准
  2. 建议使用不同的标识
  3. 应用:
package generics;//泛型class Point
{ private T x; private T y; public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } @Override public String toString() { return "Point [x=" + x + ", y=" + y + "]"; }}public class Test { public static void main(String[] args) { Point
point = new Point
(); point.setX("qwe"); point.setY("asd"); System.out.println(point); Point
point2 = new Point<>();//1.7后new后可以不写类型 point2.setX(12); point2.setY(23); System.out.println(point2); }}

运行结果

 

三、通配符

  • 引出:解决参数统一问题,可以接收所有的泛型类型,又不能让用户(main)直接修改,使用通配符
  • ?用于方法参数,指代任意类型
  1. eg:fun(MyClass<?> myclass) //表示可以接收任意类型的MyClass对象
  2. 由于类型无法确定,所以只能取得值,不能修改
  • ?extend 类 :设置泛型上限,可用于类或方法参数
  1. eg:?extend Number:表示只能接收Number或其子类
  2. 用于方法参数时,只能取得值不能修改(类型无法确定)
  • ?super 类 :设置泛型下限,只能用于方法参数
  1. ?super String :表示只能接收String或其父类(Object)
  2. 可以修改值,类型已确定,自己或父类,若此时?为父类,会默认发生向上转型
  3. 应用:
package generics;//通配符class MyClass
{ private T value; public MyClass(T value) { super(); this.value = value; } public T getValue() { return value; } public void setValue(T value) { this.value = value; }}public class Test1 { public static void main(String[] args) {// fun(new MyClass
(10)); fun(new MyClass
("qwe")); MyClass
myClass = new MyClass<>("123"); MyClass
myClass1 = new MyClass
("123"); fun(myClass); // fun(new MyClass
(10.2)); fun(new MyClass
("123")); MyClass object = new MyClass<>("123"); fun(object); } // //所有类型// public static void fun(MyClass
myClass) {// System.out.println(myClass.getValue());//适用于所有类型// } // //Number或其子类// public static void fun(MyClass
myClass) {// System.out.println(myClass.getValue());//运行结果:10 10.2// } //String或其父类Object public static void fun(MyClass
myClass) { myClass.setValue("hello"); System.out.println(myClass.getValue());//运行结果:hello }}

四、泛型接口

  • 定义:接口定义上使用此占位符<T>表示泛型接口
  • 子类实现接口:
  1. 继续保留泛型:class MyClassImpl implements MyClass<T>
  2. 声明泛型类型:class MyClassImpl implements MyClass<String>

五、泛型擦除

  • 解释:泛型是JDK1.5才引入的,而泛型能与之前的代码很好的兼容,这是因为泛型信息只存在于代码编译阶段,进入JVM之前,与泛型相关的信息会被擦除掉,这就是泛型擦除
  • 所以,在JVM中泛型类与普通类没有任何区别
  • 泛型、自动拆装箱、foreach都是Java中的语法糖(方便开发者使用,只存在于编译阶段,在运行阶段无用)
  • 在泛型类被擦除时,之前泛型类中的参数如果没有指定上限,<T>会被转译为Object,若指定上限,<T>会被转译为类型上限
你可能感兴趣的文章