zoukankan      html  css  js  c++  java
  • java~lombok的@Data引发的问题

    我们问题lombok是可以精简我们的代码的,让开发人员把精力放在业务上,而它封装的注解我们在使用时,需要多注意一下;@Data注解它是一个混合注释,它包含了@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode的功能,而我们问题@EqualsAndHashCode是重写equals和hash的注释,如果你是一个类,那可以不关心它;而如果你的类中有继承(父类子类),那么就要注意一下了。

    危险的@Data

    子类不能完全代表父类
    @EqualsAndHashCode注解里有个字段callSuper,它的默认值是false,意思是在重写时,不会将父类的字段写到equals里;而@Data这个注解由于包含了@EqualsAndHashCode,所以它也有这个特性,即子类强制实现了重写equals和hashCode,并且只重写了自己的属性,这时,问题就来了,当两个对象比较时,如果子类属性相同而父类属性不同,结果也为true,这是非常严重的bug

    定义两种类,基类People,和两个子类Man和Woman

         @Data
        class Person {
            String name;
        }
    
        @Data
        //重写时带上父类字段
        @EqualsAndHashCode(callSuper = true)
        class Man extends Person {
            Boolean hunting;
        }
    
        @Data
        //重写equals时不会带上父类的字段,同种类型比较时,当子类字段相同时,结果就为true,这显然是不准确的.
        @EqualsAndHashCode(callSuper = false)
        class Woman extends Person {
            Boolean spin;
        }
    

    测试的结果,我们是可以猜出来的,父类里的字段不相同时,结果应该为false,但如果 @EqualsAndHashCode(callSuper = false),结果竟然是true,这也是正常的,因为它并没有重写父类的属性name,所以只要子类字段相同,结果就认为相同了。

      @Test
        public void supperSubEqual() {
            Man man = new Man();
            man.setName("zzl");
            man.setHunting(true);
            Man man1 = new Man();
            man1.setHunting(true);
            man1.setName("lind");
            log.info("man==man1 ? {}", man.equals(man1)); // false
    
            Woman woman = new Woman();
            woman.setName("zzl");
            woman.setSpin(true);
            Woman woman1 = new Woman();
            woman1.setSpin(true);
            woman1.setName("lind");
            log.info("woman==woman1 ? {}", woman.equals(woman1)); // true
        }
    

    1

    总结

    在使用@Data时,我们尽量把 @EqualsAndHashCode(callSuper = true)加上,因为你不加,它相当于是false;或者杜绝使用@Data,而用@Getter,@Setter,@ToString代替它。

  • 相关阅读:
    14
    12
    11
    js 元素实现全屏和退出全屏功能
    iOS开发之使用苹果测试工具TestFlight(进行内部和外部测试)
    iOS开发之使用fastlane工具实现自动化打包发布
    iOS开发之使用MQTT协议实现远程通讯
    iOS项目功能模块封装SDK使用总结
    iOS技术之SDK开发注意事项
    iOS开发之登录注册系统
  • 原文地址:https://www.cnblogs.com/lori/p/13628140.html
Copyright © 2011-2022 走看看