我是靠谱客的博主 傲娇柜子,最近开发中收集的这篇文章主要介绍@Data取代Get,Set方法的使用总结以及注意事项@Data取代Get,Set方法的使用总结以及注意事项,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

@Data取代Get,Set方法的使用总结以及注意事项

前言:
开发过程中发现前辈的代码中实体类没有任何get,set方法但是却能正常使用get,set方法,仔细研究发现每个实体类中都使用了@Data 注解于是仔细研究了下@Data的使用方法。

介绍:
@Data 注解的主要作用是提高代码的简洁,使用这个注解可以省去代码中大量的get()、 set()、 toString()等方法;

使用:
要使用 @Data 注解要先引入lombok工具类库,可以用简单的注解形式来简化代码,提高开发效率。

在maven中添加依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.4</version>
    <scope>provided</scope>
</dependency>

注意!
在编译器中添加插件
这里以IDEA为例,在setting的plugin里搜索lombok plugin,安装插件。重启即可。

接下来就是写实体类的时候就可以直接使用这个标签了!
例如:

@Data
public class UsersDto {
    @Id
    private Integer id;
    private String name;
    private String password;
    /**
     * 性别 0男生 1女生
     */
    private Byte sex;
    private String email;
    private String city;
    }

常用的几个注解:
@Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
@AllArgsConstructor : 注在类上,提供类的全参构造
@NoArgsConstructor : 注在类上,提供类的无参构造
@Setter : 注在属性上,提供 set 方法
@Getter : 注在属性上,提供 get 方法
@EqualsAndHashCode : 注在类上,提供对应的 equals 和 hashCode 方法
@Log4j/@Slf4j : 注在类上,提供对应的 Logger 对象,变量名为 log

这样使用是不是很方便?
但是!
多年的经验告诉我,有失就有得,为什么这么好用的标签没有大面积使用呢?于是乎我深入研究了一下这个标签的使用,发现原来@Data标签还有这么多的注意事项,如果没注意的话,项目很可能出现难以预料的bug而且排查起来也很困难,下面举例说明,也顺便警醒自己和看到这篇文章的大家,如果遇到新的工具,没研究透之前,千万别贸然使用到项目中。

@Data注解它是一个混合注释,它包含了@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode的功能,而我们问题@EqualsAndHashCode是重写equals和hash的注释,如果你是一个类,那可以不关心它;而如果你的类中有继承(父类子类),那么就要注意一下了

package com.*.user;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Objects;
//@RunWith(SpringRunner.class)
//@SpringBootTest
public class LombokTest {
    @Data
    class Person {
        String name;
        int age;
    }
    @Data
    //重写时带上父类字段
    @EqualsAndHashCode(callSuper = true)
    class Man extends Person {
        Boolean hunting;
    }
    @Data
    //重写equals时不会带上父类的字段,同种类型比较时,当子类字段相同时,结果就为true,这显然是不准确的.
    @EqualsAndHashCode(callSuper = false)
    class Woman extends Person {
        Boolean spin;
    }
    @Test
    public  void tsetlombok() {
        Man t1 = new Man();
        Man t2 = new Man();
        t1.setName("123");
        t2.setName("12345");
        String name = "1";
        t1.name = name;
        t2.name = name;
        int age = 1;
        t1.age = age;
        t2.age = age;

        System.out.println(t1.equals(t2));//true
        System.out.println(t2.equals(t1));//true
        System.out.println(t1.hashCode());//376050
        System.out.println(t2.hashCode());//376050
        System.out.println(t1 == t2);//false
        System.out.println(Objects.equals(t1, t2));//true
    }

    @Test
    public void supperSubEqual() {
        Man man = new Man();
        man.setName("小张");
        man.setAge(22);
        man.setHunting(true);
        Man man1 = new Man();
        man1.setHunting(true);
        man1.setName("小李");
        man.setAge(23);
        System.out.println("man==man1?"+ man.equals(man1)); // false

        Woman woman = new Woman();
        woman.setName("小赵");
        man.setAge(19);
        woman.setSpin(true);
        Woman woman1 = new Woman();
        woman1.setSpin(true);
        man.setAge(18);
        woman1.setName("小美");
        System.out.println("woman==woman1? "+ woman.equals(woman1)); // true
    }
}

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

通过以上两个test我们发现:
父类里的字段不相同时,结果应该为false,但如果 @EqualsAndHashCode(callSuper = false),结果竟然是true,这是因为它并没有重写父类的属性name,所以只要子类字段相同,结果就认为相同了。

所以在使用@Data时,我们尽量把 @EqualsAndHashCode(callSuper = true)加上,因为你不加,它相当于是false;

优点:
1、能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,提高了一定的开发效率
2、让代码变得简洁,不用过多的去关注相应的方法
3、属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等

缺点:
1、不支持多种参数构造器的重载
2、虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性

总结:

1、用了@Data就不要有继承关系
2、自己重写equals(), Lombok 不会对显式重写的方法进行生成。
3、显式使用@EqualsAndHashCode(callSuper = true), Lombok 会以显式指定的为准。
4、或者杜绝使用@Data,而用@Getter,@Setter,@ToString代替它。

lombok 只是省去了一些人工生成代码的麻烦,但是这些getter/setter等等的方法,用IDE的快捷键也可很方便的生成。况且,有时通过给getter/setter加一点点业务代码(但通常不建议这么加),能极大的简化某些业务场景的代码。
用还是不用,这中间如何取舍,自然是要看项目的需要,灵活运用。

最后

以上就是傲娇柜子为你收集整理的@Data取代Get,Set方法的使用总结以及注意事项@Data取代Get,Set方法的使用总结以及注意事项的全部内容,希望文章能够帮你解决@Data取代Get,Set方法的使用总结以及注意事项@Data取代Get,Set方法的使用总结以及注意事项所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(135)

评论列表共有 0 条评论

立即
投稿
返回
顶部