Lombok 工具中@Data注解生成hashCode()可能导致StackOverflowError情况

本文主要是介绍Lombok 工具中@Data注解生成hashCode()可能导致StackOverflowError情况,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

看了大学一位同学博客,写了内容大致就是对于一个类中出现了该类的集合,通过Lombok的@Data注解生成class文件,当创建两个这个类的对象并且互相之间引用的时候,就出现了StackOverflowError异常,即栈溢出,或者叫超出栈深度.       
在Java虚拟机内存区域分为两种一种是线程共享区域,另一种是线程私有区域,而虚拟机栈就处在线程私有区域中,虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,栈帧用于存储局部变量表,操作数栈,动态链接,方法返回地址等等。  

 

Java 虚拟机规范中,对这个区域规定了两种异常情况:
  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。
  • 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

下面给出个内存区域内存溢出的简单测试方法,

     回到文章讨论的问题,@Data注解在什么情况下可能导致StackOverflowError情况呢?先看下同学给出的示例代码,

@Data
public class Project {private Long id;private String projectName;private List<Project> projects;public static void main(String[] args) {Project project1 = new Project();Project project2 = new Project();project1.setProjects(Arrays.asList(project2));project2.setProjects(Arrays.asList(project1));System.out.println(project1.hashCode());}
}

从代码可以看出project1引用了project2,project2引用了project1,同学给出的解释如下:“ @Data 注解不仅帮我们实现了生成了getter/setter同时还重写了equals(Object other) 和 hashCode()方法, Lombok 会将 Project 类中的 List projects 当做是 hashCode 计算的一部分(同理,equals,toString 也会存在同样的问题),而如果我的项目中出现循环引用,这就会导致死循环,最终就会抛出 StackOverFlowError。”,

        难道相互引用就一定出现死循环吗?好吧,来看看反编译下@Data到底干啥了,代码反编译后确实发现hashCode()方法被Lombok自己生成了,代码如下,

public int hashCode() {int PRIME = true;int result = 1;Object $id = this.getId();int result = result * 59 + ($id == null ? 43 : $id.hashCode());Object $projectName = this.getProjectName();result = result * 59 + ($projectName == null ? 43 : $projectName.hashCode());Object $projects = this.getProjects();result = result * 59 + ($projects == null ? 43 : $projects.hashCode());return result;
}

 

那怎么就死循环了呢,其实问题在于projects是一个ArrayList集合,而ArrayList对hashCode() 的计算会把每一个元素拿出来调用元素的hashCode()求和,但是projects里面的元素是 project,project里面又有projects,因此出现无限递归调用,又是单线程中调用方法,所以就抛出StackOverflowError,在大多数场景中我们使用Lombok的@Data注解目的是为了生成getter/setter,不需要生成hashCode()和equals()方法,即使业务需要判断两个对象是否相等,逻辑基本也不会是lombok生成的那种,所以建议使用 @Getter 和 @Setter 替换 @Data注解

ArrayList的hashCode()代码如下:

public static int hashCode(Object a[]) {if (a == null)return 0;int result = 1;for (Object element : a)result = 31 * result + (element == null ? 0 : element.hashCode());return result;
}

 

 

这篇关于Lombok 工具中@Data注解生成hashCode()可能导致StackOverflowError情况的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1124637

相关文章

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

Linux系统之stress-ng测压工具的使用

《Linux系统之stress-ng测压工具的使用》:本文主要介绍Linux系统之stress-ng测压工具的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、理论1.stress工具简介与安装2.语法及参数3.具体安装二、实验1.运行8 cpu, 4 fo

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

Java 关键字transient与注解@Transient的区别用途解析

《Java关键字transient与注解@Transient的区别用途解析》在Java中,transient是一个关键字,用于声明一个字段不会被序列化,这篇文章给大家介绍了Java关键字transi... 在Java中,transient 是一个关键字,用于声明一个字段不会被序列化。当一个对象被序列化时,被

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

MybatisX快速生成增删改查的方法示例

《MybatisX快速生成增删改查的方法示例》MybatisX是基于IDEA的MyBatis/MyBatis-Plus开发插件,本文主要介绍了MybatisX快速生成增删改查的方法示例,文中通过示例代... 目录1 安装2 基本功能2.1 XML跳转2.2 代码生成2.2.1 生成.xml中的sql语句头2

Python使用Turtle实现精确计时工具

《Python使用Turtle实现精确计时工具》这篇文章主要为大家详细介绍了Python如何使用Turtle实现精确计时工具,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录功能特点使用方法程序架构设计代码详解窗口和画笔创建时间和状态显示更新计时器控制逻辑计时器重置功能事件

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File