• lombok插件各个注解介绍


    内容參考網址:https://blog.csdn.net/sunsfan/article/details/53542374

    lombok插件各个注解介绍

    一、IDEA下载和配置lombok

    打开IDEA,点击File 》 Settings…
    在这里插入图片描述
    然后点击Plugins(插件),在Marketplace里面搜索 Lombok 下载即可。(这里我因为已经下载好了,所以他存放的位置是 Installed)
    在这里插入图片描述
    下载完成后,我们只需要在我们的项目中引入依赖就可以使用啦!配置信息如下:

    
    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
    dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <version>2.7.2version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    之后我们就可以直接使用我们Lombok插件的各种注解啦!!!下面我们说一下各个注解的作用。

    二、Lombok各注解介绍

    lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁。废话少说,我们直接来看看Lombok常用的一些注解。

    2.1 @NonNull

    这个注解可以用在成员方法或者构造方法的参数前面,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常,举个例子来看看:

    //成员方法参数加上@NonNull注解
    public String getName(@NonNull Person p){
        return p.getName();
    }
    
    • 1
    • 2
    • 3
    • 4

    上面的代碼就相當於:

    public String getName(@NonNull Person p){
        if(p==null){
            throw new NullPointerException("person");
        }
        return p.getName();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    再者,我们来个构造器的例子:

    Employee(@NonNull String id, @NonNull String name,Integer age, Boolean gender, @NonNull Double salary){
    	this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.salary = salary;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    該代碼就等價於:

    Employee(@NonNull String id, @NonNull String name,Integer age, Boolean gender, @NonNull Double salary){
    	if(id == null){
    		throw new NullPointerException("id");
    	}
    	if(name == null){
    		throw new NullPointerException("name ");
    	}
    	if(salary == null){
    		throw new NullPointerException("salary");
    	}
    	this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.salary = salary;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.2 @Cleanup

    这个注解用在变量前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法,就用输入输出流来举个例子吧:

    public static void main(String[] args) throws IOException {
         @Cleanup InputStream in = new FileInputStream(args[0]);
         @Cleanup OutputStream out = new FileOutputStream(args[1]);
         byte[] b = new byte[1024];
         while (true) {
           int r = in.read(b);
           if (r == -1) break;
           out.write(b, 0, r);
         }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    該代碼就等價於:

    public static void main(String[] args) throws IOException {
         InputStream in = new FileInputStream(args[0]);
         try {
           OutputStream out = new FileOutputStream(args[1]);
           try {
             byte[] b = new byte[10000];
             while (true) {
               int r = in.read(b);
               if (r == -1) break;
               out.write(b, 0, r);
             }
           } finally {
             if (out != null) {
               out.close();
             }
           }
         } finally {
           if (in != null) {
             in.close();
           }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.3 @Getter/@Setter

    这一对注解从名字上就很好理解,用在成员变量前面,相当于为成员变量生成对应的get和set方法,同时还可以为生成的方法指定访问修饰符,当然,默认为public,直接来看下面的简单的例子:

    public class Programmer{
        @Getter
        @Setter
        private String name;
    
        @Setter(AccessLevel.PROTECTED)
        private int age;
    
        @Getter(AccessLevel.PUBLIC)
        private String language;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    該代碼就等價於:

    public class Programmer{
        private String name;
        private int age;
        private String language;
    
        public void setName(String name){
            this.name = name;
        }
    
        public String getName(){
            return name;
        }
    
        protected void setAge(int age){
            this.age = age;
        }
    
        public String getLanguage(){
            return language;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    不過我們經常性的話,都是直接在類上面加,類似這樣:

    @Getter
    @Setter
    public class Programmer{
        private String name;
    
        private int age;
    
        private String language;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    該代碼就等價於:

    public class Programmer{
        private String name;
    
        private int age;
    
        private String language;
        
    	public void setName(String name){
            this.name = name;
        }
    
        public String getName(){
            return name;
        }
    
        public void setAge(int age){
            this.age = age;
        }
    
    	public String getAge(){
            return age;
        }
    
        public void setLanguage(int language){
            this.language= language;
        }
    
        public String getLanguage(){
            return language;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2.4 @ToString

    这个也比较好理解,就是帮我们生成toString方法,帮我们输出所有的属性。直接代码走起:

    @ToString
    @Setter
    @Getter
    public class Student {
        private String id;
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    然後我們寫個測試方法來檢驗一下我們的成果:

    public class StudentServiceTest {
        @Test
        public void testToString(){
            Student student = new Student();
            student.setId("1001");
            student.setName("小明");
            student.setAge(18);
            Map<String, Double> gradeMap = new HashMap<>();
            gradeMap.put("語文", 80.5d);
            gradeMap.put("數學", 99d);
            gradeMap.put("英語", 93.5d);
            student.setGrade(gradeMap);
            System.out.println(student);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    輸出結果如下:
    在这里插入图片描述

    2.5 @EqualsAndHashCode

    這個注解主要是幫我們生成三個方法:equals、hashcode、canEqual。其中用得比較多的可能就是我們的equals方法了,那麽他生成的equals方法都做了啥咧,其實也很簡單,就是調用它裏面所有屬性的equals方法,如果都爲true,那麽就返回true。舉個例子:

    实体类代码如下:

    @ToString
    @Setter
    @Getter
    @EqualsAndHashCode
    public class Student {
        private String id;
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试方法如下:

    public void testEqualsAndHashCode(){
        Student student1 = new Student();
        student1.setId("1001");
        student1.setName("小明");
        student1.setAge(18);
        Map<String, Double> gradeMap1 = new HashMap<>();
        gradeMap1.put("語文", 80.5d);
        gradeMap1.put("數學", 99d);
        gradeMap1.put("英語", 93.5d);
        student1.setGrade(gradeMap1);
    
        Student student2 = new Student();
        student2.setId("1001");
        student2.setName("小明");
        student2.setAge(18);
        Map<String, Double> gradeMap2 = new HashMap<>();
        gradeMap2.put("語文", 80.5d);
        gradeMap2.put("數學", 99d);
        gradeMap2.put("英語", 93.5d);
        student2.setGrade(gradeMap2);
        System.out.println(student1.equals(student2));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    输出结果:
    在这里插入图片描述

    2.6 @NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor

    Constructor翻译成中文其实就是构造器的意思。所以,我们的这三个注解(@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor)其实就是生成三种构造器,分别是

    • NoArgsConstructor:无参构造器
    • RequiredArgsConstructor:為@NonNull注解和final修飾的成員變量生成特定参数构造方法。
    • AllArgsConstructor:全参构造器

    第一个和第三个比较简单,假如现在我们的实体类如下:

    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
        private String id;
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    該代碼就等價於:

    public class Student {
        private String id;
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    
    	public Student(){}
    
    	public Student(String id, String name, Integer age, Map<String, Double> grade) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.grade = grade;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    至於 @RequiredArgsConstructor 這個注解嘛,廢話少説,直接代碼開擼。

    @ToString
    @RequiredArgsConstructor(staticName = "getEasiestStudent")
    public class Student {
        private final String id;
        @NonNull
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    等價於:

    public class Student {
        private final String id;
        @NonNull
        private String name;
        private Integer age;
        private Map<String, Double> grade;
    
    	public Student(String id, @NonNull String name){
    		this.id = id;
    		this.name = name;
    	}
    
    	public static Student getEasiestStudent(String id, String name){
    		return new Student(id, name);
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如果我們@RequiredArgsConstructor不加 (staticName = “getEasiestStudent”) 這一串,直接用的話,寫的是 @RequiredArgsConstructor注解的話,那麽就只為所有的final字段還有@NonNull注解生成一個構造方法。

    	public Student(String id, @NonNull String name){
    		this.id = id;
    		this.name = name;
    	}
    
    • 1
    • 2
    • 3
    • 4

    2.7 @Data

    @Data這個注解好像是開發中最常用的,因爲他整合了我們前面的好幾個注解——@Setter、@Getter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor。當然了,如果你想使用@RequiredArgsConstructor生成靜態構造方法的功能的話,你也可以使用 @Data(staticConstructor=”methodName”) 來生成你想要的構造方法。

    2.8 @Value

    @Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。

    2.9 @SneakyThrows

    这个注解用在方法上,可以将方法中的代码用try-catch语句包裹起来,捕获异常并在catch中用Lombok.sneakyThrow(e)把异常抛出,可以使用@SneakyThrows(Exception.class)的形式指定抛出哪种异常,很简单的注解,直接看个例子:

    public class SneakyThrows implements Runnable {
        @SneakyThrows(UnsupportedEncodingException.class)
        public String utf8ToString(byte[] bytes) {
            return new String(bytes, "UTF-8");
        }
    
        @SneakyThrows
        public void run() {
            throw new Throwable();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    等價於:

    public class SneakyThrows implements Runnable {
        @SneakyThrows(UnsupportedEncodingException.class)
        public String utf8ToString(byte[] bytes) {
            try{
                return new String(bytes, "UTF-8");
            }catch(UnsupportedEncodingException uee){
                throw Lombok.sneakyThrow(uee);
            }
        }
    
        @SneakyThrows
        public void run() {
            try{
                throw new Throwable();
            }catch(Throwable t){
                throw Lombok.sneakyThrow(t);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.10 @Synchronized

    这个注解用在类方法或者实例方法上,效果和synchronized关键字相同,区别在于锁对象不同,对于类方法和实例方法,synchronized关键字的锁对象分别是类的class对象和this对象,而@Synchronized得锁对象分别是 private static final 对象lock,当然,也可以自己指定锁对象,例子也很简单,往下看:

    public class Synchronized {
        private final Object readLock = new Object();
    
        @Synchronized
        public static void hello() {
            System.out.println("world");
        }
    
        @Synchronized
        public int answerToLife() {
            return 42;
        }
    
        @Synchronized("readLock")
        public void foo() {
            System.out.println("bar");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    等價於:

    public class Synchronized {
       private static final Object $LOCK = new Object[0];
       private final Object $lock = new Object[0];
       private final Object readLock = new Object();
    
       public static void hello() {
         synchronized($LOCK) {
           System.out.println("world");
         }
       }
    
       public int answerToLife() {
         synchronized($lock) {
           return 42;
         }
       }
    
       public void foo() {
         synchronized(readLock) {
           System.out.println("bar");
         }
       }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.11 @Log

    这个注解用在类上,可以省去从日志工厂生成日志对象这一步,直接进行日志记录,具体注解根据日志工具的不同而不同,同时,可以在注解中使用topic来指定生成log对象时的类名。不同的日志注解总结如下(上面是注解,下面是实际作用):

    @CommonsLog
    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
    @JBossLog
    private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
    @Log
    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
    @Log4j
    private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
    @Log4j2
    private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
    @Slf4j
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
    @XSlf4j
    private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    举个例子吧:
    比如我们现在使用的是Slf4j作为我们的日志配置工具,那么我们本来每一个Controller应该都要写一句private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(StudentController.class); 用於輸出我們具体的日志信息的,但是其实大可不必,我们只需要在我们的Controller类上面加上注释 @Slf4j 就可以了。
    即,现有代码如下:

    @RestController
    @Slf4j
    public class StudentController{
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    等價於:

    @RestController
    public class StudentController{
    	private static final Logger log = LoggerFactory.getLogger(StudentController.class);
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    内容參考網址:https://blog.csdn.net/sunsfan/article/details/53542374

  • 相关阅读:
    WFP实现侧边栏导航菜单
    Java 最常见的面试题:常用的 jvm 调优的参数都有哪些?
    十六、垃圾回收相关概念
    一句话总结设计模式
    TFHE 的全同态模结构(FHE Module Structure)
    用于制作耳机壳的倒模专用UV树脂有什么特点?
    Linux查看内核和系统版本信息
    a标签下载文件与解决浏览器默认打开某些格式文件的问题
    无序去重代码
    Kafka 集群安装
  • 原文地址:https://blog.csdn.net/weixin_44741023/article/details/127745165