《Java架构筑基》从Java基础讲起——泛型的使用

发布时间:2020-06-21 05:50:04 作者:未来可期_
来源:网络 阅读:284

一. 泛型的使用

1. 泛型类的概述及使用

2. 泛型方法的概述和使用

public <T> void show(T t) {

}

所谓泛型方法,就是在声明方法时定义一个或多个类型形参。 泛型方法的用法格式如下:

修饰符<T, S> 返回值类型 方法名(形参列表){
   方法体
}

注意要点

class Demo{  
  public <T> T fun(T t){   // 可以接收任意类型的数据  
   return t ;     // 直接把参数返回  
  }  
};  
public class GenericsDemo26{  
  public static void main(String args[]){  
    Demo d = new Demo() ; // 实例化Demo对象  
    String str = d.fun("汤姆") ; // 传递字符串  
    int i = d.fun(30) ;  // 传递数字,自动装箱  
    System.out.println(str) ; // 输出内容  
    System.out.println(i) ;  // 输出内容  
  }  
};

3. 泛型接口的概述和使用

先来看一个案例

/**
 * 泛型接口的定义格式:        修饰符  interface 接口名<数据类型> {}
 */
public interface Inter<T> {
    public abstract void show(T t) ;
}

/**
 * 子类是泛型类
 */
public class InterImpl<E> implements Inter<E> {
    @Override
    public void show(E t) {
        System.out.println(t);
    }
}

Inter<String> inter = new InterImpl<String>() ;
inter.show("hello") ;

然后看看源码中泛型的使用,下面是JDK 1.5 以后,List接口,以及ArrayList类的代码片段。

//定义接口时指定了一个类型形参,该形参名为E
public interface List<E> extends Collection<E> {
   //在该接口里,E可以作为类型使用
   public E get(int index) {}
   public void add(E e) {} 
}

//定义类时指定了一个类型形参,该形参名为E
public class ArrayList<E> extends AbstractList<E> implements List<E> {
   //在该类里,E可以作为类型使用
   public void set(E e) {
   .......................
   }
}

这就是泛型的实质:允许在定义接口、类时声明类型形参,类型形参在整个接口、类体内可当成类型使用,几乎所有可使用普通类型的地方都可以使用这种类型形参。

泛型类派生子类

public class A extends Container<K, V>{}
public class A extends Container<Integer, String>{}
public class A extends Container{}

4. 泛型类的概述和使用

定义一个容器类,存放键值对key-value,键值对的类型不确定,可以使用泛型来定义,分别指定为K和V。

public class Container<K, V> {

    private K key;
    private V value;

    public Container(K k, V v) {
        key = k;
        value = v;
    }

    public K getkey() {
        return key;
    }

    public V getValue() {
        return value;
    }

    public void setKey() {
        this.key = key;
    }

    public void setValue() {
        this.value = value;
    }

}

在使用Container类时,只需要指定K,V的具体类型即可,从而创建出逻辑上不同的Container实例,用来存放不同的数据类型。

public static void main(String[] args) {
    Container<String,String>  c1=new Container<String ,String>("name","hello");
    Container<String,Integer> c2=new Container<String,Integer>("age",22);
    Container<Double,Double>  c3=new Container<Double,Double>(1.1,1.3);
    System.out.println(c1.getKey() + " : " + c1.getValue());      
    System.out.println(c2.getKey() + " : " + c2.getValue());                                                               
    System.out.println(c3.getKey() + " : " + c3.getValue());
}

在JDK 1.7 增加了泛型的“菱形”语法:Java允许在构造器后不需要带完成的泛型信息,只要给出一对尖括号(<>)即可,Java可以推断尖括号里应该是什么泛型信息。 如下所示:

Container<String,String> c1=new Container<>("name","hello");
Container<String,Integer> c2=new Container<>("age",22);

5. 泛型构造器的概述

这里唯一需要特殊注明的就是:

如果构造器是泛型构造器,同时该类也是一个泛型类的情况下应该如何使用泛型构造器:因为泛型构造器可以显式指定自己的类型参数(需要用到菱形,放在构造器之前),而泛型类自己的类型实参也需要指定(菱形放在构造器之后),这就同时出现了两个菱形了,这就会有一些小问题,具体用法再这里总结一下。

以下面这个例子为代表

public class Person<E> {
    public <T> Person(T t) {
        System.out.println(t);
    }
}

这种用法:Person<String> a = new <Integer>Person<>(15);这种语法不允许,会直接编译报错!

二. 泛型高级之通配符

1. 为什么要使用通配符

通配符的设计存在一定的场景,例如在使用泛型后,首先声明了一个Animal的类,而后声明了一个继承Animal类的Cat类,显然Cat类是Animal类的子类,但是List却不是List的子类型,而在程序中往往需要表达这样的逻辑关系。为了解决这种类似的场景,在泛型的参数类型的基础上新增了通配符的用法。

2. <? extends T> 上界通配符

上界通配符顾名思义,<? extends T>表示的是类型的上界【包含自身】,因此通配的参数化类型可能是T或T的子类。

它表示集合中的所有元素都是Animal类型或者其子类
List<? extends Animal>

这就是所谓的上限通配符,使用关键字extends来实现,实例化时,指定类型实参只能是extends后类型的子类或其本身。

//Cat是其子类
List<? extends Animal> list = new ArrayList<Cat>();

3. <? super T> 下界通配符

下界通配符<? super T>表示的是参数化类型是T的超类型(包含自身),层层至上,直至Object

它表示集合中的所有元素都是Cat类型或者其父类
List <? super Cat>

这就是所谓的下限通配符,使用关键字super来实现,实例化时,指定类型实参只能是extends后类型的子类或其本身。

例如:

//Shape是其父类
List<? super Cat> list = new ArrayList<Animal>();

4. <?> ***通配符

三. 泛型只能使用引用类型

当声明泛型类的实例时,传递的类型参数必须是引用类型,不能使用基本类型

如何解决

推荐阅读:
  1. 《Java架构筑基》从Java基础讲起——泛型擦除
  2. 《Java架构筑基》从Java基础讲起——泛型基础

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java 泛型 后端开发

上一篇:nagios监控服务出现FLAPPING状态时无法发出邮件报警信息

下一篇:ECMAScript Array

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》