【Java高级】泛型

本文详细介绍了Java中的泛型,包括泛型的基本概念、引入泛型的原因、泛型的优缺点、类型自动推断、泛型方法、泛型类和泛型接口的使用,以及泛型的边界限定。通过实例展示了泛型如何提高代码类型安全性,减少类型转换的麻烦,并探讨了泛型在实际编程中的应用。
摘要由CSDN通过智能技术生成

一.泛型介绍

(1) 是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
(2)泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

二.例子

我们这里有一个案例,我们创建一个集合,然后将new出来的不同对象放到同一个集合当中。我们注意到(1)行的obj只能是Object类型。所以我们如果想要调用Animal或者Cat或者Bird的方法,只能向下转型,而向下转型之前又要判断,比较麻烦。

package com.sdnu;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author Beyong
 * @Description generics
 * @date 2021/07/06 18:32
 */

public class generics {
    public static void main(String[] args) {
        Cat c = new Cat();
        Bird b = new Bird();
        Collection myList = new ArrayList();
        myList.add(c);
        myList.add(b);
        Iterator it = myList.iterator();
        while(it.hasNext()){
            Object obj = it.next();//**************************(1)
            if(obj instanceof Animal){
                Animal a = (Animal)obj;
                a.animalMove();
            }
            if(obj instanceof Cat){
                Cat a = (Cat)obj;
                a.catchMouse();
            }
            if(obj instanceof Bird){
                Bird a = (Bird)obj;
                a.birdFly();
            }
        }
    }
}
class Animal {
    public void animalMove(){
        System.out.println("Animal is moving");
    }
}
class Cat extends Animal {
    public void catchMouse(){
        System.out.println("Cat catch mouse");
    }
}
class Bird extends Animal {
    public void birdFly(){
        System.out.println("Bird is fly");
    }
}


三.引入泛型

针对上面例子的问题,我们引入泛型,如(2)所示,我们指定了集合中的类型为Animal,所以存储在该集合中的所有元素均为Animal.

package com.sdnu;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author Beyong
 * @Description generics
 * @date 2021/07/06 18:32
 */

public class generics {
    public static void main(String[] args) {
        Cat c = new Cat();
        Bird b = new Bird();
        Collection<Animal> myList = new ArrayList<Animal>();//***(2)
        myList.add(c);
        myList.add(b);
        Iterator<Animal> it = myList.iterator();
        while(it.hasNext()){
            Animal a = it.next();
            a.animalMove();
            if( a instanceof Cat){
                Cat a1 = (Cat)a;
                a1.catchMouse();
            }
            if( a instanceof Bird){
                Bird a1 = (Bird)a;
                a1.birdFly();
            }
        }
    }
}
class Animal {
    public void animalMove(){
        System.out.println("Animal is moving");
    }
}
class Cat extends Animal {
    public void catchMouse(){
        System.out.println("Cat catch mouse");
    }
}
class Bird extends Animal {
    public void birdFly(){
        System.out.println("Bird is fly");
    }
}


四.泛型优缺点

优点:

集合中的存储元素统一。

集合中取出的元素的类型都是泛型指定的类型,减少了向下转型。

缺点:

导致集合中的元素多样性减少。

五.类型自动推断

在JDK8.0之后,我们的泛型可以使用自动类型判断机制,也称"钻石表达式"。
简单来说,就是上面例子的(2)可以改为如下

Collection myList = new ArrayList<>();//***(2)

后面<>中的参数类型能根据前面推出。

六.泛型方法

我们可以写一个泛型方法,在方法声明的返回值类型前加一个<>,在其中添加一个标识符,比如下面的E(不是关键字,任取都可以,只是一般来说,E代表Element,T代表Type),在泛型中可以声明多个类型参数。为了指定两个或更多个类型参数,只需要使用逗号分隔参数列表即可。

package com.sdnu.generics;

/**
 * @author Beyong
 * @Description genericsMethod
 * @date 2021/07/07 14:18
 */

public class genericsMethod {
    public static <E> void printElement( E[] object){
        for(E element : object){
            System.out.print(element);
        }
        System.out.println("");
    }
    public static void main(String[] args) {
        Integer[] integerObject = {1,2,3,4,5,6};
        Double[] doubleObject = {1.0,2.0,3.0,4.0,5.0,6.0};
        String[] stringObject = {"kk", "mm", "ll", "pp"};
        printElement(integerObject);
        printElement(doubleObject);
        printElement(stringObject);
    }
}



在这里插入图片描述

七.泛型类

与泛型方法类似,我们在类名后面加类型参数声明部分。

package com.sdnu.generics;

/**
 * @author Beyong
 * @Description genericsTest
 * @date 2021/07/07 12:27
 */

public class Test1<T> {
    public void methodTest (T temp) {
        System.out.println(temp);
    }

    public static void main(String[] args) {
        Test1<String> object = new Test1<>();
        object.methodTest("kkkkk");
    }
}



八.泛型接口

既然类可以使用泛型,那么接口当然也可以使用泛型。

package com.sdnu.generics;

/**
 * @author Beyong
 * @Description genericsInterface
 * @date 2021/07/07 16:30
 */

public class Test2 {
    public static void main(String[] args) {
        Cat object = new Cat();
        String s = object.move("myCat");
        System.out.println(s);
    }
}
interface Animal <T>{
    T move(T t);
}
class Cat implements Animal<String>{
    public String move(String s){
        return s + "catch mouse";
    }
}


九.边界限定

类型的上界,格式为:<? extends T>,即类型必须为T类型或者T子类

如下面的例子
在这里插入图片描述

类型的下界,格式为:<? super T>,即类型必须为T类型或者T的父类

如下面的例子

在这里插入图片描述

作者:台北的雨    
出处:Beyong博客
github地址:https://github.com/beyong2019


本博客中未标明转载的文章归作者Beyong所有有,欢迎转载,但未经作者同意必须保留此段声明,且在文章明显位置给出原文连接,否则保留追究法律责任的权利。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值