什么是堆污染 heap pollution

堆污染发生在使用可变参数(varargs)或泛型时,将不兼容的类型插入到一个泛型对象中。这会导致在运行时尝试访问这些对象时发生 ClassCastException。例如:

public static void heapPollutionExample(List<String>... stringLists) {
Object[] array = stringLists;
array[0] = Arrays.asList(42); // 这里会引起堆污染
String s = stringLists[0].get(0); // ClassCastException
}

在这个例子中,heapPollutionExample 方法接收一个 List<String> 的可变参数,但在运行时,可以将 List<Integer> 插入其中,从而引发堆污染。

在上面的示例中,IDEA会发出下面的警告,并提示加上@SafeVarargs注解:

Possible heap pollution from parameterized vararg type (参数化变量类型可能造成堆污染)

我们在方法上加上@SafeVarargs注解,警告就消失了。

@SafeVarargs注解

@SafeVarargs 注解本身并不能完全避免堆污染风险。它的作用是告诉编译器和开发者,这个方法不会对其可变参数(varargs)进行不安全的操作,

从而避免了不必要的警告,很像@SuppressWarnings注解。也就是说,它是一种承诺和保证,表明方法的实现是安全的,并不会引发堆污染。

使用范围:

在Java 7中,@SafeVarargs 只能用于静态方法final 实例方法。这是因为只有这些方法可以保证不会被子类重写,从而避免堆污染风险。

在Java 9中,@SafeVarargs 注解的使用范围扩展到了 private 实例方法JEP213

java中堆污染(heap pollution)以及@SafeVarargs注解使用的更多相关文章

  1. java安全编码指南之:堆污染Heap pollution

    目录 简介 产生堆污染的例子 更通用的例子 可变参数 简介 什么是堆污染呢?堆污染是指当参数化类型变量引用的对象不是该参数化类型的对象时而发生的. 我们知道在JDK5中,引入了泛型的概念,我们可以在创 ...

  2. Java中堆(heap)和栈(stack)的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...

  3. java中堆和堆栈的区别

    java中堆和堆栈的区别(一) 1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取 ...

  4. Java中堆与栈

    简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...

  5. 让你彻底明白JAVA中堆与栈的区别

    原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...

  6. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  7. Java中堆和栈的区别(转)

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

  8. 《挑战30天C++入门极限》新手入门:C++中堆内存(heap)的概念和操作方法

        新手入门:C++中堆内存(heap)的概念和操作方法 堆内存是什么呢? 我们知道在c/c++中定义的数组大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作 ...

  9. Java的堆(Heap)和栈(Stack)的区别

    Java中的堆(Heap)是一个运行时数据区,用来存放类的对象:栈(Stack)主要存放基本的数据类型(int.char.double等8种基本数据类型)和对象句柄. 例1 int a=5; int ...

  10. Java中堆内存和栈内存的区别

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空 ...

随机推荐

  1. Q:oracle如何查询表和视图的等修改时间和创建时间?

    要查询表的修改时间,可以使用以下SQL语句: SELECT object_name, object_type, created, last_ddl_time FROM user_objects WHE ...

  2. Q:Linux符号连接的层数过多

    创建符号链接的时候源文件一定要使用绝对路径,尤其是链接不在同一目录时候,用相对路径会出现这种bug,具体是红色闪烁状态.:正常应该是青绿色  例如: 安装zabbix_agent遇到的问题,在root ...

  3. Git指南-从入门到精通

    代码提交和同步命令 流程图如下: 第零步: 工作区与仓库保持一致 第一步: 文件增删改,变为已修改状态 第二步: git add ,变为已暂存状态 $ git status $ git add --a ...

  4. C语言编程技巧 全局变量在多个c文件中公用的方法

    在使用C语言编写程序时,经常会遇到这样的情况:我们希望在头文件中定义一个全局变量,并将其包含在两个不同的C文件中,以便这个全局变量可以在这两个文件中共享.举个例子,假设项目文件夹"proje ...

  5. captura怎样解决FFmpeg解析错误问题

    captura怎样解决FFmpeg解析错误问题?captura软件里大家在进行屏幕录制的工作得时候都会用到captura软件,软件得功能可以满足大家的需求,可以轻松的录制屏幕,进行屏幕截屏等,但是又小 ...

  6. Zookeeper - 客户端常用命令

    查看客户端命令帮助信息 查看Zookeeper的版本 查看使用过的历史命令 查看根目录下的znode 创建znode 查看节点信息 修改znode的内容 删除znode 关闭连接 连接客户端 退出客户 ...

  7. mysql 获取数据库名、表名、字段名、根据表结构创建新表

    1.查询当前使用的数据库 select database(): 2.获取当前数据库表 select * from information_schema.TABLES where TABLE_SCHEM ...

  8. apache和nginx關聯php的過程

    Nginx端 Nginx是一個服務器,同時也是一個功能強大的proxy服務器,除了進行http請求的代理,還可以進行其他協議請求代理(fastCgi協議),為了能使nginx理解fastCgi協議,n ...

  9. 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫

    目录 什么是 Selenium 环境搭建与配置 安装 Selenium 下载浏览器驱动 基础操作 启动浏览器并访问网页 定位网页元素 通过 ID 定位 通过 CSS 选择器定位 通过 XPath 定位 ...

  10. Vulnhub-sundown

    总结:该靶机是一个wordpress管理系统,需要信息收集得到插件信息,然后搜索插件漏洞,得到一个文件包含exp,利用其得到一个普通用户,利用hydra爆破密码然后ssh连接,信息收集得到一个数据库配 ...