我认不到你 2023-10-13 17:25 采纳率: 100%
浏览 15
已结题

关于String的薛定谔的猫

为什么解开注释和放开注释是两个不同的值


    @Test
    public void test2() throws NoSuchFieldException, IllegalAccessException {
        
        String a = "a";
        // 为什么这里放开和解开是两个不同的值
        System.out.println("放开"+a.hashCode());
        char[] c = {'c'};
        Class<? extends String> aClass = a.getClass();
        Field value = aClass.getDeclaredField("value");
        value.setAccessible(true);
        value.set(a,c);

        System.out.println(a.hashCode());

    }

放开:

img

不放开:

img

  • 写回答

2条回答 默认 最新

  • 我认不到你 2023-11-07 11:29
    关注

    这是由于String重写的hashCode的方法,先在对象中存了一个int的属性 hash,在执行hashCode的时候hash由于是基本属性,所以是0,在第一次执行时存了个hash值,由于是一个对象(地址是一样的,可以通过System.out.println(Integer.toHexString(System.identityHashCode(a)));查看地址值),后面就算改变了value,hash也不会变
    同理如果只在最后运行hashCode方法,那么hash由于没有改变过,还是0,那么就执行if分支,赋值hash为新的值,由于value改变了(就是通过反射改变的),所以得到的hash值也是不一样的

        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月15日
  • 已采纳回答 11月7日
  • 创建了问题 10月13日