栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

理解Java泛型和类型擦除

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

理解Java泛型和类型擦除

目录

介绍

泛型标记

泛型限定

上限

下限

泛型方法

泛型类

泛型接口

类型擦除

  泛型擦除的体现

对象放进List
​​​​​​​

介绍

泛型的本质是参数化类型,泛型提供了编译时类型的安全检测机制,该机制允许程序在编译时检测非法的类型,比如要实现一个能够对字符串(String)、整形(Int)、浮点型(float)、对象(Object)进行大小比较的方法,就可以使用泛型。

泛型标记
序号泛型标记说明
1E-Element在集合中使用,表示在集合中存放的元素
2T-Type表示Java类,包括基本的类和我们自定义的类
3K-Key表示键,比如Map中的Key
4V-value表示值
5N-Number表示数值类型
6?表示不确定的Java类型(类型通配符也可以使用)

泛型限定

上限

使用通配符"?"和"extends"关键字指定泛型的上限,具体用法是,表示该通配符所代表的类型是T类的子类或者接口T的子接口。

下限

使用通配符"?"和"super"关键字指定泛型的上限,具体用法是,表示该通配符所代表的类型是T类型的父类或者父接口。

https://www.cnblogs.com/lucky_dai/p/5485421.html

泛型方法

泛型方法指将方法的参数类型定义为泛型,以便在调用的时候接收不同类型的参数。

package fanxing;

import java.util.Date;

public class GenericClassTest {
    public static void main(String[] args) {
        genericMethod(1,1.1D,1.2F);
    }

    public static  void genericMethod(T... param){
        for (T  element : param){
            if(element instanceof Integer){
                System.out.println("处理 Integer 类型数据中...");
            }
            else if(element instanceof Double){
                System.out.println("处理 Double 类型数据中...");
            }
            else if(element instanceof Float){
                System.out.println("处理 Float 类型数据中...");
            }
            else if(element instanceof Long){
                System.out.println("处理 Long 类型数据中...");
            }
            else if(element instanceof Date){
                System.out.println("处理 Date 类型数据中...");
            }
            
        }
    }
}

泛型类

泛型类指在定义类时在类上定义了泛型,以便类在使用时可以根据传入的不同参数类型实例化不同的对象。

package fanxing;

public class GenericClassTest {
    public static void main(String[] args) {
        GenericClassTest list = new GenericClassTest<>();
        list.add(11);
        GenericClassTest strList = new GenericClassTest<>();
        strList.add("111");
    }
    private T t;
    
    public void add(T t){
        this.t = t;
    }
    
    public T get(){
        return t;
    }
}

泛型接口

泛型接口和泛型类类似,通过在接口名后面添加类型参数的声明部分来实现。

package fanxing;


public interface TGeneric {
    T getId();
}
package fanxing;

import java.util.Random;


public class GenericIntergerTest implements TGeneric {
    @Override
    public Integer getId() {
        Random random = new Random();
        return random.nextInt();
    }

    public static void main(String[] args) {
        GenericIntergerTest test = new GenericIntergerTest();
        System.out.println(test.getId());
    }

}

类型擦除

     泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。

    泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。

      JVM并不知道泛型的存在,因为泛型在编译阶段就已经被处理成普通的类和方法; 
处理机制是通过类型擦除,擦除规则:

若泛型类型没有指定具体类型,用Object作为原始类型;若有限定类型< T exnteds XClass >,使用XClass作为原始类型;若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;

  泛型擦除的体现

在写代码时,无法把一个 String 类型的实例加到 ArrayList 中,因为ArrayList 和 ArrayList 在编译的时候是完全不同的类型,但是运行结果却是true。这就Java泛型的类型擦除造成的。

因为不管是 ArrayList 还是 ArrayList,在编译完成后都会被编译器擦除成了 ArrayList。

Java 泛型擦除是 Java 泛型中的一个重要特性,其目的是避免过多的创建类而造成的运行时的过度消耗。所以,想 ArrayList 和 ArrayList 这两个实例,其类实例是同一个。


对象放进List

当我们正常的将 Activity 对象放进 List list = new ArrayList<>( ) 这样的集合去,会报一个错:

 泛型的约束让我们无法将 Activity 对象放进泛型为 String 的集合中去。那么咋整呢?

通过泛型擦除的体现已经知道ArrayList(或者ArrayList)编译后都是java.util.ArrayList,泛型的约束是在编译时约束的,真正运行的 class 是没有泛型约束的。所以只要在运行时将 Activity 对象加入List中就可以了:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782610.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号