泛型详解

Posted 凯玲之恋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型详解相关的知识,希望对你有一定的参考价值。

泛型详解

泛型概述

泛型概述:限定集合存储的数据类型,Collection<E>其中E代表引用数据类型,如果加上了该引用数据类型,表示该集合中只能存储改类型对象,或者该类型的子类对象

泛型用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。

泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。

泛型的由来

当没有指定泛型时,默认类型为Object类型。Object代表任意的数据类型(所有类都是object的子类),(返回值类型是object类型,所以用object接收,要存成其他,需要强转,代码繁琐)objext什么都可以接受,

泛型定义格式

1)泛型类:

概述

在类上定义泛型,类名后<泛型变量> class A<E> 使用:

定义格式

    public class 类名<泛型类型1,…>

确定泛型

创建对象时确定具体的类型

2)泛型方法:

概述:

在方法上定义泛型.

定义格式

要在权限修饰符后面返回值类型的前面<泛型变量>

        public <泛型类型> 返回类型 方法名(泛型类型 变量名)

public <T> void method(){使用T}

确定泛型

调用方法时,确定具体的数据类型

案例:

  1. public class Tool<Q> {//在类上定义了泛型Q,Q什么时候有值,当你用这个类时,指定了泛型是什么,Q就代表什么
  2.    private Q q;
  3.    public Q getObj() {
  4.       return q;
  5.    }
  6.  
  7.    public void setObj(Q q) {
  8.       this.q = q;
  9.    }
  10.  
  11.    public void write(Q q){ //write方法使用类上定义的泛型
  12.       System.out.println(q);
  13.    }
  14.    public <T> void show(T t) { //方法泛型最好与类的泛型一致
  15.       System.out.println(t); //如果不一致,需要在方法上声明该泛型
  16.    }
  17.    public static<W> void print(W w) { //静态方法必须声明自己的泛型
  18.       System.out.println(w);
  19.    }
  20.  
  21. }
  22. import com.kailing.bean.Student;
  23. import com.kailing.bean.Tool;
  24. import com.kailing.bean.Worker;
  25.  
  26. public class Demo3_Generic {
  27.  
  28.    public static void main(String[] args) {
  29.  
  30.       Tool<String> t = new Tool<>();
  31.       //t.write("abc");
  32.       t.show(true);
  33.    }
  34. }

 

静态方法与非静态方法泛型:

非静态方法,对类的泛型可用可不用.

静态方法, 不能使用类的泛型,想使用泛型,必须定义自己的泛型.

因为静态方法随着类的加载而加载,在类加载后,可能还没有创建对象呢,所以此时静态方法上的泛型可能没值

在调用该静态方法时被赋值   

 

3)泛型接口

概述

把泛型定义在接口上 如: interface B<T>{使用T完成接口定义}

定义格式:

public interface 接口名<泛型类型>

确定泛型:

1、子类在实现接口的同时,直接给出具体的泛型

  1. class Cat implements Fly<String> {
  2.    public void fly(String t) {
  3.    }
  4. }

2、子类继续沿用接口的泛型(其实子类就变成泛型类了),在创建子类对象的时候确定泛型

  1. class Cat<T> implements Fly<T> {
  2.    public void fly(T t) {
  3.    }
  4. }

 

泛型好处

     提高安全性

将运行期的错误转换到编译期

     省去强转的麻烦

优化程序设计

注意事項

泛型基本使用

     <>中放的必须是引用数据类型 

     前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)  

 

 

 

案例一

  1. 泛型类:
  2.  public class DemoType02<T> {//T是泛型变量
  3.    //使用泛型定义成员变量
  4.    private T field;
  5.    public T getField() {//方法中使用到类中的泛型不是泛型方法
  6.       return field;
  7.    }
  8.    public void setField(T field) {//方法中使用到类中的泛型
  9.       this.field = field;
  10.    }
  11.    public static void main(String[] args) {
  12.       泛型类的使用过程
  13.       //创建对象,确定泛型类型,通过对象,操作对应的数据类型
  14. DemoType02<String> dt2 = new DemoType02<String>();
  15.       dt2.setField("abc");
  16.       String field2 = dt2.getField();
  17.       System.out.println(field2);
  18.       }
  19.    //泛型方法
  20.    public <E> void method(E e) {
  21.       System.out.println(e);
  22.    }
  23.  
  24. dt2.method(100);//调用后方法是integer类型
  25. 泛型只能是引用类型
  26. }

案例二

  1.  定义接口泛型:接口名<泛型变量>
  2. public interface MyInterface<T> {
  3. public abstract T method();
  4.    public abstract void method(T t);
  5. }
  6. 泛型接口在定义子类时,直接指定类型
  7. public class MyClass4Interface implements MyInterface<String> {
  8.    public void method(String t) {
  9.       System.out.println("参数是字符串"+t);
  10.    }
  11. }
  12. 泛型接口在定义子类时,没有确定数据类型.(定义了泛型子类)
  13. public class MyClass4Inter face2<T> implements MyInterface<T> { public void method(T t) {
  14.       System.out.println(t);
  15.    }
  16. }
  17. public class DemoType03 {
  18.   public static void main(String[] args) {
  19.       //当泛型接口在定义类时,已经确定了数据类型,则创建对象时,直接使用即可
  20.       MyClass4Interface mc4i = new MyClass4Interface();
  21.       mc4i.method("abc");
  22.       泛型使用2
  23.       //当泛型接口在定义类时,没有确定数据类型,则创建对象时,仍需指定泛型类型
  24.       MyClass4Interface2<Integer> mc4i2 = new MyClass4Interface2<Integer>();
  25.       mc4i2.method(100);
  26.    }
  27.  
  28. }

    泛型的通配符

    1)概述:

泛型通配符:英文半角状态下的 ?

泛型通配符代表任意数据类型,不能像泛型一样作为某一种数据类型单独使用

2)使用场景:

? extends E

叫法:固定上边界(向下限定);

作用:代表只要是E类型的子类即可

? super E

叫法:固定下边界(向上限定)

作用:代表只要是E类型的父类即可

? 代表传进来的参数的泛型        E 代表调用方法对象的泛型

 

案例三

  1. import java.util.ArrayList;
  2. //public ArrayList(ArrayList<? extends E> c) 通过参数,创建新的集合
  3. public class DemoType04 {
  4.  public static void main(String[] args) {
  5.    ArrayList<String> list = new ArrayList<String>();
  6.      list.add("abc");
  7.      list.add("abc2");
  8.      list.add("abc3");
  9.      list.add("abc4");
  10.  //传入的参数其泛型String 是创建对象的泛型Object类型的 子类 符合泛型规定? extends E
  11. ArrayList<Object> list2 = new ArrayList<Object>(list);
  12.      System.out.println(list2);
  13.    }
  14. }

 

以上是关于泛型详解的主要内容,如果未能解决你的问题,请参考以下文章

转载Java泛型详解

Java泛型详解

泛型详解

Java泛型详解,史上最全图文详解!

Java泛型详解

Java泛型详解(转)