`
soundworld
  • 浏览: 27550 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

枚举的hashcode跨JVM不稳定

阅读更多
碰到的问题: 在工程中试图给你一个POJO添加一个版本号的属性,由于考虑时间因素因此选择了用这个对象的一些属性的hashcode作为版本号,如果那些属性都没有改变那么这个hashcode不应该改变,反之则改变. 在这些属性中偏巧..有一些是枚举类型. 在测试中发现,如果使用同一个JVM一直调用程序,那么该hashcode一直相同,但是如果重启服务器,开新的JVM,那么这个hashcode将会改变,即使对应的Object的任何属性都没有改变.这就是枚举的hashcode跨JVM不稳定.

调查发现: 在JDK中的Enum.class中 hashcode方法是final的并且直接调用父类Object.class的hashcode方法
/**
     * Returns a hash code for this enum constant.
     *
     * @return a hash code for this enum constant.
     */
    public final int hashCode() { //不允许子类重写
        return super.hashCode();
    }


这样,枚举的hashcode就和内存地址挂钩也就可能会产生不稳定.google了下这个问题,已经有人给oracle提出bug要求将上面的方法去掉final修饰,不过oracle拒绝了 - -

个人目前的解决方法是调用枚举的name()方法将其转化为String,String的hashcode是稳定的.

一个记录.
分享到:
评论

相关推荐

    JAVA字符串类型switch的底层原理详析

    在JVM中,switch语句的处理可以分为两步:首先,JVM会将字符串类型转换为hashCode,然后使用hashCode进行比较。如果hashCode相同,则会使用equals方法对比字符串的值。 在上面的代码示例中,我们可以看到,JVM将...

    面试小抄第二版.pdf

    7. **switch语句**:在Java 7之后,switch可以用于String类型,但不能用于long,因为long不是原始类型的枚举。 8. **访问修饰符**:public允许所有类访问,private限制在同一类内,protected允许同一包内或子类访问...

    scjp笔记

    - **枚举比较**:不能直接比较枚举对象的大小,但可以通过`ordinal()`方法获取每个枚举实例的序号并进行比较。 - **枚举方法调用**:枚举实例可以调用其定义的方法。 #### 类与接口 - **接口实现**:类可以实现多个...

    1.pdf

    switch语句不支持byte、long和String,但在Java 7之后,switch可以接受枚举类型和String。计算效率上,用移位操作()计算2乘以8最快。Math.round()函数将浮点数四舍五入为最接近的整数,对于正数和负数,分别会向正...

    观看韩顺平学习整理java的笔记到异常

    Java编程语言是面向对象的,其异常处理机制、对象生命周期管理、类的构造与方法、代码块、枚举、注解等概念都是开发者必须掌握的关键知识点。以下是对这些概念的详细解析: 1. **hashCode**: 在Java中,`hashCode()...

    java effective 第二版中英文二份文件

    7. **利用final、static和private修饰符优化类和方法**:这些修饰符可以提升性能,例如,static方法不会隐式地持有对调用它的对象的引用,因此可以被JVM优化。 8. **避免过度使用final**:虽然final可以增加代码的...

    基础篇.pdf

    Java是跨平台的语言,通过JVM(Java虚拟机)实现。除了Java,JVM还支持Kotlin、Groovy、JRuby、Jython、Scala等其他语言。值传递和引用传递是参数传递的两种方式,Java中所有参数传递都是值传递,即使是对象也是对象...

    java基础反射IO流线程模式

    - **`hashCode()`**:返回枚举常量的哈希码。 - **`name()`**:返回此枚举常量的名称,在其枚举声明中对其进行声明。 - **`ordinal()`**:返回枚举常量的序数(即它在枚举声明中的位置,其中初始常量序数为零)。 - ...

    Java基础笔记(包括底层原理)

    在深入理解Java时,了解JVM(Java虚拟机)的工作原理是至关重要的,因为它是Java代码能够跨平台运行的关键。 JVM是Java程序的运行环境,它将编译后的字节码转换为特定操作系统下的机器指令。JDK(Java Development ...

    Java 面试知识点总结.pdf

    其中,boolean 类型的大小在《Java 虚拟机规范》中没有明确定义,在 JVM 中没有专门的字节码指令来操作 boolean 值,而是使用 int 类型来代替。在数组中,每个 boolean 元素占 1 字节,但单独使用时占 4 字节。这是...

    Java中的语法糖.docx

    但是,Java编译器允许对String和枚举类型的switch-case,通过计算String的hashCode或枚举的ordinal值来实现。 2. **泛型**:泛型提供了一种方式来指定集合和其他容器类的数据类型,增加了类型安全,减少了类型转换...

    java编码规范考试题答案.pdf

    9. **安全编程**:需要对输入进行验证,禁止不受信任的代码终止JVM,创建文件时设定适当权限,记录日志时不应抛出异常。 10. **获取用户名**:可以通过JVM属性获取操作系统登录用户名,如`System.getProperty("user...

    133道Java面试题及答案(面试必看)

    Java基础,如equals和hashCode的正确使用,泛型和枚举的理解,以及异常处理,也是面试的重点。对于equals和hashCode,面试者需要理解它们在对象比较中的作用,以及如何重写这两个方法以满足自定义需求。泛型提供了...

    编码规范考试题答案.pdf

    - 不允许不受信任的代码直接结束JVM。 - 创建文件时应设定适当的访问权限。 - 记录日志时不应抛出异常,而应妥善处理。 10. **获取操作系统用户名**: - 可通过JVM属性`System.getProperty("user.name")`获取...

    JAVA面试题总览[整理].pdf

    17. 单例模式常见的实现有:饿汉式、懒汉式(线程不安全)、双重检查锁定、静态内部类、枚举。 18. 自动完成hashcode和equals实现,可以使用IDE的代码生成工具,便于维护一致性。优点是避免因重写不当引发的问题,...

    Java程序员反馈的百度的笔试题.docx

    常见的实现方式有饿汉式(静态常量)、懒汉式(线程不安全的、线程安全的synchronized和双重检查锁定)以及枚举单例。 4. **重写equals方法与hashCode方法**: 当重写equals方法时,通常也需要重写hashCode方法,...

    Java面试题大汇总(附答案)

    但switch不支持long类型,只支持byte、short、char、int、枚举类型以及从Java 1.7开始的字符串。 11. **String对象的intern()方法**:此方法会检查字符串常量池中是否存在该字符串值,如果存在则返回常量池中的引用...

    java面试经典题目和答案

    如果不重写 `hashCode()` 方法,可能会导致即使两个对象相等也无法正确地在哈希表中查找,这违反了哈希表的基本工作原理。 #### 总结 Java 面试涉及的知识点广泛且深入,除了上述列举的几个方面外,还包括异常处理...

    Java注解学习1-Java Annotation认知(包括框架图、详细介绍、示例说明)

    它们并不直接影响程序的执行,但可以用于代码分析、编译时验证或者运行时处理。本文将详细介绍Java Annotation的基本概念、语法和用法,以及它们的框架结构。 首先,了解Annotation的架构至关重要。一个Annotation...

Global site tag (gtag.js) - Google Analytics