面向对象之封装性介绍以及Lombok使用简介

大家好,因为项目中牵涉到很多pojo,dto类,这些类在创建之后会经常修改,如果我每次修改完都去删除旧的gerter/setter和toString,就会很麻烦,所以今天给大家介绍一下Lombok——一种更优雅的形式来实现动态加载getter/setter等方法的插件。

 

一、背景介绍

我们都知道,面向对象的三个特性——封装、继承、多态

封装——封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,客户只需要知道怎么操作,不需要知道操作的原理和细节。

采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。这样就避免了外部操作对内部数据的影响,提高了程序的可维护性。

举个很简单的例子,你在使用鼠标,鼠标就是被封装的整体,你只能使用鼠标的按键来实现操作,并不能打开,也不需要打开,这样就保证了你的鼠标的使用寿命,否则谁知道你拆下来再装回去会不会多一个螺丝呢。

二、知识刨析

封装的一般实现——给成员变量加上private,保证其是私有的,然后通过public的get/set来操作数据,任何有值可以被运用到的地方,都可以用调用方法的方式来取得改类型的值。

面向对象之封装性介绍以及Lombok使用简介_第1张图片

从上图可以看到,设为私有的属性就只能被当前类调用,而那个Public方法就是当前类中的,刚好可以操作此属性,而其方法本身是public是可以被是所有包调用的,这样就保证了数据的封装性。

封装的作用——给你的实例变量加上绝对领域,这样就没有人可以瞎鸡儿操作你的变量了。首先保证了数据的私密性,数据不能被无代价的查看或者修改,同时也不能超出其本身应该有的范围。其强迫其他程序对数据的操作一定要经过get/set,这样的话,我就可以在get/set中对数据进行一定的操作。比如去小数,判断范围,对不合理的值抛出异常,甚至直接启动自爆程序!

举个例子:

下面是两个实体类,一个使用了封装,一个未使用

public class Cat {
    //将数据公开
    public String name;
    public float weight;
    public float height;
    
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                ", height=" + height +
                '}';
    }
}
public class Dog {
    //将数据封装
    private String name;
    private float weight;
    private float height;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(name.equalsIgnoreCase("bitch")){
            System.out.println("侮辱,小狗很生气,将采取自爆模式");
        }
            this.name = name;
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        if(weight>0.05)
        this.weight = weight;
        else
            this.weight=0.05f;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        if(height>0.1)
        this.height = height;
        else
            this.height=0.1f;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                ", height=" + height +
                '}';
    }
}

然后是一个启动类,创建两个对象

public class Main {
    public static void main(String[] args) {
        Cat cat=new Cat();
        cat.name="mimi";
        cat.height=-5;
        cat.weight=0;

        System.out.println(cat);

        Dog dog=new Dog();
        dog.setHeight(-5);
        dog.setWeight(0);
        System.out.println(dog);
    }
}

我们知道,小猫小狗的身高体重肯定不可能是负数,是存在一个范围的,所以看结果

面向对象之封装性介绍以及Lombok使用简介_第2张图片

Cat类因为没有使用封装,所以用户输入什么就是什么,没有数据合理性的校验,也不能对其进行其他功能性的设置,Dog类则可以对输入的数据进行判断,从而增加了程序灵活性。

三、常见问题

那get/set重复写很麻烦,咋办呢?

四、解决方案

1.使用编译器自带的快捷键Alt+Ins,选择相对应的方法即可

面向对象之封装性介绍以及Lombok使用简介_第3张图片

2.使用Lombok插件

lombok——其在程序编译时自动扫描注解加载需要的诸如get/set,toString等方法,可以消除冗长的代码,实现优雅编码,特别是对于pojo这种简单的java对象。

使用方法:添加依赖——安装插件——添加注解——使用

依赖如下

 
        
            org.projectlombok
            lombok
            1.16.10
        

安装插件,在IDEA中,可以使用自带的插件商店下载安装

面向对象之封装性介绍以及Lombok使用简介_第4张图片

注意:如果安装不成功,需要去git上根据idea版本手动下载对应的插件,

面向对象之封装性介绍以及Lombok使用简介_第5张图片

再安装即可

面向对象之封装性介绍以及Lombok使用简介_第6张图片

然后即可以在pojo类中添加注解来实现免写getter/setter了

lombok常用注解介绍

@Getter,@Setter,可以写在单独的实体变量上,会生成对应的无参构造和getter/setter方法。

@Data,该注解使用在类上,该注解会提供getter、setter、equals、canEqual、hashCode、toString方法。虽然@Data注解非常有用,但是它没有与其他注解相同的控制粒度。

@NonNull,该注解使用在属性上,该注解用于属的非空检查,当放在setter方法的字段上,将生成一个空检查,如果为空,则抛出NullPointerException。该注解会默认是生成一个无参构造。

@toString,该注解使用在类上,该注解默认生成任何非讲台字段以名称-值的形式输出。

1、如果需要可以通过注释参数includeFieldNames来控制输出中是否包含的属性名称。

2、可以通过exclude参数中包含字段名称,可以从生成的方法中排除特定字段。

3、可以通过callSuper参数控制父类的输出。

@EqualsAndHashCode,该注解使用在类上,该注解在类级别注释会同时生成equals和hashCode。

@AllArgsConstructor,该注解使用在类上,该注解提供一个全参数的构造方法,默认不提供无参构造。

@NoArgsConstructor,该注解使用在类上,该注解提供一个无参构造

@RequiredArgsConstructor,该注解使用在类上,使用类中所有带有 @NonNull 注解的或者带有 final 修饰的成员变量生成对应的构造方法。

@Value这个注解用在 类 上,会生成含所有参数的构造方法,get 方法,此外还提供了equals、hashCode、toString 方法。

注意:没有setter,相当于@Data-@Setter

我们需要根据自己的需要灵活使用

五、更多讨论

1.多人合作开发,其他人没有安装插件,你写的代码使用了@Data注解的话,其他人可以实现调用吗?

不可以,否则也不会要求必须安装插件了。

2.有人会说了,我们平时的get/set其实根本就没有做事啊,就是简单的一键生成,那么我为啥不把它去掉呢?留着它岂不是白白增加负担吗?

其实这样做的好处就是增加了程序的可维护性,也许暂时我们现在不需要对其进行判断,但当我们后面需要修改时,你不可能将所有使用过的地方都再改为get/set吧?

3.如果我想在setter/getter中增加判断条件,怎么办呢?

可以使用单注解,然后手写需要添加条件的注解

六、参考文献

https://blog.csdn.net/motui/article/details/79012846

 

今天的分享就到这了,大家有什么问题可以评论里留言,觉得不错也可以点个赞哦~

 

你可能感兴趣的:(lombok)