热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中的类型擦除

Java中的类型擦除原文:https://www.geeksf

Java 中的类型擦除

原文:https://www.geeksforgeeks.org/type-erasure-java/

先决条件: 泛型
泛型概念是在 Java 语言中引入的,以在编译时提供更严格的类型检查,并支持泛型编程。实现泛型的方法,Java 编译器将类型擦除应用于:


  • 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为它们的边界或对象。因此,生成的字节码只包含普通的类、接口和方法。

  • 如有必要,插入类型转换以保护类型安全。

  • 生成桥接方法以在扩展泛型类型中保留多态性。

一般来说,编译后的泛型代码实际上只使用 java.lang.Object,无论您在哪里谈论 T(或其他类型参数)——并且有一些元数据告诉编译器它确实是泛型类型。当您针对泛型类型或方法编译一些代码时,编译器会计算出您真正的意思(即 T 的类型参数是什么),并在编译时验证您正在做正确的事情,但是发出的代码仍然只是用 java.lang.Object 的术语说话——编译器会在必要时生成额外的强制转换。在执行时,列表和列表完全相同;额外的类型信息已被编译器删除。

根据计划,类型擦除是如何工作的?

// Here, T is bounded by Object i.e. java.lang.Object
class GFG<T> {
// Here, T will be replaced by default i.e. Object
    T obj; 
    GFG(T o)
    {
        obj = o;
    }
    T getob()
    {
        return obj;
    }
}

编译后,代码被默认对象替换,如下所示:

class GFG
{
// Here, T will be replaced by default i.e. Object
Object obj;
GFG(Object o)
{
obj=o;
}
Object getob()
{
return obj;
}
}


// Here, T is bounded by Object i.e. java.lang.Object
class Geeks<T extends String> {
 // Here, T will be replaced by String i.e. java.lang.String
    T str;
    Geeks(T o)
    {
        str = o;
    }
    T getob()
    {
        return str;
    }
}

编译后,代码替换为如下字符串:

class Geeks
{
//Here, T will be replaced by String i.e. java.lang.String
String str;
Geeks(String o)
{
str=o;
}
String getob()
{
return str;
}
}

注:以上两个类编译完成后,我们可以同时查看两个类的内容。编译后,在 GFG,类 T 将被对象替换,在极客类 T 将被字符串替换。我们可以通过运行 javap className 命令编译的代码来检查内容。

类型擦除实施

// Java program to illustrate
// concept of TypeErasure
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenericsErasure {
    public static void main(String args[])
    {
        List<String> list = new ArrayList<String>();
        list.add("Hello");
        Iterator<String> iter = list.iterator();
        while (iter.hasNext()) {
            String s = iter.next();
            System.out.println(s);
        }
    }
}

解释:这里我们在编译代码的时候,它不会向控制台屏幕抛出任何警告消息,因为这里我们使用的是 Type Erasure。

// Java program to illustrate
// concept of TypeErasure
import java.io.PrintStream;
import java.util.*;
public class GenericsErasure {
    public GenericsErasure()
    {
    }
    public static void main(String args[])
    {
        List list = new ArrayList();
        list.add("Hello");
        String s;
        for (Iterator iter = list.iterator(); iter.hasNext();
             System.out.println(s))
            s = (String)iter.next();
    }
}

解释:在这里,当我们编译代码时,我们会从编译器那里得到一些提示,即 GenericsErasure.java 使用了未经检查或不安全的操作。

参考:
类型擦除
堆栈溢出


推荐阅读
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
author-avatar
永远在等一个人--嘉儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有