Lombok浅析
什么是Lombok
一个典型的Java类
public class A {
    private int num;
    private String str;
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof A)) return false;
        A a = (A) o;
        if (getNum() != a.getNum()) return false;
        return getStr() != null ? getStr().equals(a.getStr()) : a.getStr() == null;
    }
    @Override
    public int hashCode() {
        int result = getNum();
        result = 31 * result + (getStr() != null ? getStr().hashCode() : 0);
        return result;
    }
    @Override
    public String toString() {
        return "A{" + "num=" + num + ", str='" + str + '\'' + '}';
    }
}
对于这样一个简单的 Java 类,我们通常需要给每个属性写 getXXX() 和 setXXX() 方法,有时候还要重写 equals()、 hashCode()、
toString()等方法。在开发的过程中,重复编写这些“没有技术含量”的代码,对程序员来说是一个很枯燥无趣的事情,也增加了很大的工作负担。
针对这种情况,Lombok 提供了一种机制,基于注解的方式,帮助我们自动生成这些样板代码。如:
@Data
public class A {
    private int a;
    private String b;
}
@Data 就是 Lombok 的一个注解,它所做的工作包括生成了所有属性的 getXXX() 和 setXXX() 方法,重写了equals()、 hashCode()、
toString() 方法。
将 lombok.jar 拷贝到 A.java 文件所在目录进行编译:
javac -cp lombok.jar A.java && javap -public A.class
public class com.tuniu.calliper.component.view.controller.A {
   public com.tuniu.calliper.component.view.controller.A();
   public int getNum();
   public java.lang.String getStr();
   public void setNum(int);
   public void setStr(java.lang.String);
   public boolean equals(java.lang.Object);
   public int hashCode();
   public java.lang.String toString();
 }
可以看到生成的方法。反观未加入 @Data 注解的 A.java, 编译后为:
public class com.tuniu.calliper.component.view.controller.A {
   public com.tuniu.calliper.component.view.controller.A();
 }
使用
具体的安装和引入可参考 Lombok官网。需要说明的是,如果 IDE 不安装插件,同样可以通过编译,但是,在IDE中会提示报错,
并在编写代码时,不会出现方法提示,影响使用。
Lombok的运行机制
Lombok主要基于Java中的注解生成代码,以@Setter方法为例(具体源码可查看 Lombok项目源码),其注解定义如下:
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
	lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
	AnyAnnotation[] onMethod() default {};
	AnyAnnotation[] onParam() default {};
	@Deprecated
	@Retention(RetentionPolicy.SOURCE)
	@Target({})
	@interface AnyAnnotation {}
}
可以发现,@Setter 是源码级别的,即在编译期有效。我们知道,在 Java 中,Java 编译主要分为三大部分:
- 分析和输入到符号表
- 注解处理(可选)
- 语义分析和生成 class 文件
Lombok 的注解都是在编译期的第二个阶段,也就是注解处理阶段去解析注解,并生成对应的源码,然后重新编译修改后的源文件,最后在class文件中包含对应的方法。
需要注意的是,在 javac 编译器中,注解处理 机制是默认打开的,而对于 eclipse 这种自带编译器( ECJ )的 IDE 是默认不打开的,这也就是为什么 IDE 要安装插件
的原因。
Lombok注解
Lombok 目前最新版本为1.16.8,主要提供16种注解,个人觉得比较常用的有以下几种,更多可查看 Lombok官网。
- 
@Getter / @Setter 
 作用于属性和类上,自动生成属性的getXXX()和setXXX()方法。若在类上,则对所有属性有效。并可通过AccessLevel参数控制方法的访问级别。
- 
@ToString 
 作用于类,自动重写类的ToString()方法。常用的参数有exclude(指定方法中不包含的属性)、callSuper(方法中是否包含父类ToString()方法返回的值)
- 
@EqualsAndHashCode 
 作用于类,自动重写类的equals()、hashCode()方法。常用的参数有exclude(指定方法中不包含的属性)、callSuper(方法中是否包含父类ToString()方法返回的值)
- 
@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor 
 作用于类,@NoArgsConstructor自动生成不带参数的构造方法;@RequiredArgsConstructor自动生成带参数的构造方法,主要针对一些需要特殊处理的属性,比如未初始化的final属性;
 @AllArgsConstructor自动生成包含所有属性的构造方法。
- 
@Data 
 @ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstructor注解的集合。
- 
@Synchronized 
 作用于方法,可锁定指定的对象,如果不指定,则默认创建创建一个对象锁定。
- 
@Log 
 作用于类,具体包含@CommonsLog、@Log、@Log4j、@Log4j2、@Slf4j和@XSlf4j,分别对用不同的日志系统。利用此类注解,可为类创建一个log属性。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号