IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 泛型——简要概述 -> 正文阅读

[Java知识库]泛型——简要概述

引用:

B站韩顺平 零基础30天学会java

菜鸟教程-Java泛型

泛型介绍

?

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

??Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常(也就是类型安全检测机制),同时,代码更加简洁、健壮。

下面用一个实例详细分析:
??编写程序,在ArrayList中,添加3个Dog对象。Dog对象中有name属性,并输出name(要求使用getName())

  • 这里的ArrayList没有<>,其中存储的类型是Object
import java.util.ArrayList;

public class Demo01 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(new Dog("来福"));
        arrayList.add(new Dog("旺财"));
        arrayList.add(new Dog("狗蛋"));
        //如果程序员不小心添加了其他类!
        arrayList.add(new Cat("小花"));
        for(Object o : arrayList){
            //向下转型 Object ==> Dog
            Dog dog = (Dog) o;
            System.out.println("这里有狗!叫"+dog.getName());
        }
    }
}

class Dog{
    private String name;
    public Dog(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Cat{
    private String name;
    public Cat(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
}
  • 这里假如!假如!程序员在编写代码时,不小心多添加了一个别的类的实例对象到ArrayList中,代码显示时是没有异常的!这样是存在隐患的,同时编译器是发现不了。在运行之后,会发生报错,类型转换异常!
    在这里插入图片描述

  • 使用这种传统的方法不能对加入到集合ArrayList中的数据类型进行约束(不安全)。同时在遍历时,需要进行类型转换,如果集合中的数据量较大,对效率会存在影响

当使用泛型之后

  • 编译器发现了ArrayList添加到类型不满足要求,会报错(没使用泛型是发现不了的),这样在编译时就提高了安全性
  • 遍历时,可以直接取出Dog类型,不用类型转换,节省效率!

在这里插入图片描述


那么,泛型到底是什么?简单来说,泛型就是——一个表示数据类型的数据类型!

泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型。

class Person<E>{
    E s;// E表示 s 的数据类型,该数据类型在定义Person对象时指定,即在编译期间,就确定E是什么类型
    
    public Person(E s) {//E也可以是参数类型
        this.s = s;
    }
    
    public E f(){//也可以是返回类型
        return s;
    }
}	

假定有这样一个需求:写一个排序方法,能够对整形数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是使用Java泛型

使用Java泛型的概念,可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整数型数组、浮点数数组、字符串数组等进行排序。

泛型方法

定义泛型方法的规则

  • 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数部分在方法返回类型前

  • 每一个类型参数声明部分包括一个或多个类型参数,参数键用逗号隔开。一个泛型参数,也被称为一个类型变量,适用于指定一个泛型类型名称的标识符

  • 类型参数能被用来声明返回值类型,并且作为泛型方法得到的实际参数类型的占位符

  • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用类型,不能是原始类型(像int、double、char等)

java中的泛型标记符

  • E Element(在集合中使用,因为集合中存在放的是元素

  • T Type(java类)

  • K key(键)

  • V Value(值)

  • N Number(数值类型)

  • ? 表示不确定的java类型

实例

下面的列子演示如何使用泛型方法打印不同类型的元素

public class Demo02 {
    //泛型方法
    public static <E> void printArray(E[] inputArray){
        //输出元素数组
        for(E element : inputArray){
            System.out.print(element+"  ");
        }
    }

    public static void main( String args[] ) {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组

        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组

        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    }
}

运行结果为:

在这里插入图片描述

有界的参数类型

??指限制被允许传递到一个类型参数的类型范围。例如,一个操作数字的方法可能只接受Number或者Number子类的实例。这就是有界类型参数参数的目的。要声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,然后跟紧他的上界。

public class Demo03 {
    // 比较三个值并返回最大值
    public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
        T max = x; // 假设x是初始最大值
        if ( y.compareTo( max ) > 0 ){
            max = y; //y 更大
        }
        if ( z.compareTo( max ) > 0 ){
            max = z; // 现在 z 更大
        }
        return max; // 返回最大对象
    }
    public static void main( String args[] ) {
        System.out.println( "3,4,5 中最大的数为"+ maximum( 3, 4, 5 ) );
        System.out.println( "6.6, 8.8, 7.7 中最大的数为" + maximum( 6.6, 8.8, 7.7 ));
        System.out.println( "pear,apple,orange中最大的数为" + maximum( "pear", "apple", "orange" ));
    }
}

泛型类

??泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分

??和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。

public class Box<T> {
    private T t;
    public void add(T t){
        this.t = t;
    }
    public T get(){
        return t;
    }

    public static void main(String[] args) {
        Box<Integer> box1 = new Box<>();
        Box<String> box2 = new Box<>();

        box1.add(13);
        box2.add("mikasa");

        System.out.println("整数型值为:" + box1.get());
        System.out.println("字符串型值为:" + box2.get());
    }
}

? 运行结果:

在这里插入图片描述

类型通配符

??类型通配符一般是使用?代替具体的类型参数。例如List<?>在逻辑上是List<String>,List<Integer>等所有List<具体类型实参>的父类

??类型通配符的上限通过形如List<? extends Number>来定义,如此定义就是通配符泛型值接受Number及其下子层类类型。

import java.util.ArrayList;
import java.util.List;

public class Demo04 {
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();

        name.add("mikasa");
        age.add(13);
        number.add(624);

//        getUperNumber(name); 
        getUperNumber(age);
        getUperNumber(number);

    }

    public static  void getData(List<?> data){
        System.out.println("data:" + data.get(0));
    }

    public static void getUperNumber(List<? extends Number> data){
        System.out.println("data:" +data.get(0));
    }
}

//输出结果
//data:18
//data: 314

//getUperNumber(name); 会出现错误,因为 getUperNumber() 方法中的参数已经限定了参数泛型上限为 Number,所以泛型为 String 是不在这个范围之内,所以会报错。

??类型通配符下限通过形如List<? super Number>来定义,表示类型只接受Number及其上层父类类型,如Object类型的实例

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:12:19  更:2021-11-23 12:15:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:07:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码