Java 泛型 泛型类 通配符 泛型中父子类型

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

泛型是java1.5中增加的一个新特性,通过泛型可以写与类型无关的代码,即编写的代码可以被很多不同类型的对象所重用,经常用在一些通用的代码实现中,比如:java集合框架中的类几乎都是用泛型实现的。
泛型的本质是:类型参数化。类似函数传参一样,传递不同的实参,函数运行完将会产生不同的结果

1.泛型类

class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, …, Tn> {
// 类实现体
}

规范】类型形参一般使用一个大写字母表示,常用的名称有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
S, U, V 等等 - 第二、第三、第四个类型

简单实例

// 当对泛型类进行实例化时,编译器才知道E具体代表什么类型
public class MyArray<E> {
    private E[] array = null;
    private int size;
    private int capacity;
    public MyArray(int capacity){
    // 此处为什么new Object[],为什么需要强转后文中会解释
        array = (E[])new Object[capacity];
        size = 0;
        this.capacity = capacity;
    }
    public void add(E data){
        if(size < capacity)
            array[size++] = data;
    }
    public E get(int index){
        return array[index];
    }
    public int size(){
        return size;
    }
}


public class Main {
    public static void main(String[] args) {
// 将泛型类使用String类型来实例化,表明m中只能存放String类型的对象
        MyArray<String> m = new MyArray<>(10);
        m.add("Peter");
        m.add("David");
        m.add("Jim");

        for(int i = 0; i < m.size(); ++i){
// 此处从m中获取到的成员,再不需要进行强制类型转换了
            String s = m.get(i);
            System.out.print(s + " ");
        }
        System.out.println();
        System.out.println("-------------");
        MyArray<Integer> n= new MyArray<>(2);
        n.add(2);
        n.add(3);
        n.add(4);

        for(int i = 0; i < n.size(); ++i){
            int a = n.get(i);
            System.out.println(a);
        }
    }
}


在这里插入图片描述

2.泛型方法

方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { … }

简单实例

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
       Integer[] ar={0,1,2,3,4,5,6,7,8,9};
       swap(ar,0,9);
       System.out.println(Arrays.toString(ar));

       String[] s1={"a","b"};
       swap(s1,0,s1.length-1);
       System.out.println(Arrays.toString(s1));
    }
    public static <E> void swap(E[] array, int i, int j) {
        E t = array[i];
        array[i] = array[j];
        array[j] = t;
    }
 }

在这里插入图片描述

3.泛型类使用–通配符

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束

class 泛型类名称 {

}
在实例化时,E只能是U的子类,否则编译会报错

基本

// 可以传入任意类型的 MyArray
public static void printAll(MyArray<?> m) {

}

// 以下调用都是正确的
printAll(new MyArray());
printAll(new MyArray());
printAll(new MyArray());
printAll(new MyArray());
printAll(new MyArray());

通配符-上界

<? extends 上界>
// 传入类型实参是 Animal 子类的任意类型的 MyArray

public static void printAll(MyArray<? extends Animal> m) {

}

// 以下调用都是正确的
printAll(new MyArray());
printAll(new MyArray());
// 以下调用是编译错误的
printAll(new MyArray());
printAll(new MyArray());

通配符-下界

<? super 下界>
// 可以传入类型实参是 Cat 父类的任意类型的 MyArray
public static void printAll(MyArray<? super Cat> list) {

}
// 以下调用都是正确的
printAll(new MyArrayList());
printAll(new MyArrayList());
printAll(new MyArrayList());
// 以下调用是编译错误的
printAll(new MyArrayList());
printAll(new MyArrayList());

4.泛型中父子类型

public class MyArray { … }
// MyArray 不是 MyArray 的父类型
// MyArray 也不是 MyArray 的父类型
// 需要使用通配符来确定父子类型
// MyArray<?> 是 MyArray<? extends Animal> 的父类型
// MyArray<? extends Animal> 是 MyArrayList 的父类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值