Lombok插件使用

添加依赖

Maven添加依赖 pom.xml 文件

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.6</version>
    </dependency>
</dependencies>

Gradle添加依赖 build.gradle 文件

dependencies {
    compileOnly "org.projectlombok:lombok:1.18.6"
}

 

注解

val & var

import lombok.val;
import java.util.HashMap;
import java.util.Map;

public class AnswerAIL {

    public static void main(String[] args) {

        withLombok();

        System.out.println("\n##############################\n");

        withoutLombok();
    }


    
    private static void withLombok() {
        val map = new HashMap<String, String>();
        map.put("name", "answer");
        map.put("email", "answer_ljm@163.com");
        map.put("address", "pt");

        // val 声明的局部变量为 final 类型, 因此以下代码编译会出错
        // 把 val map = ... 替换成  var map = ... 以下代码编译就不会出错
        map = new HashMap<String, String>();
        
        for (String key: map.keySet()) {
            System.out.println(String.format("key[%s]\t\tvalue[%s]", key, map.get(key)));
        }
    }

    private static void withoutLombok() {
        Map<String, String> map = new HashMap<>();
        map.put("name", "answer");
        map.put("email", "answer_ljm@163.com");
        map.put("address", "pt");

        for (String key: map.keySet()) {
            System.out.println(String.format("key[%s]\t\tvalue[%s]", key, map.get(key)));
        }
    }

}

说明: var 和 val 功能类似(作为局部变量声明的类型), 异同点: val 声明出来的局部变量为 final 类型

@NonNull

import lombok.Data;
import lombok.NonNull;

public class AnswerAIL {

    public static void main(String[] args) {

        withLombok();

        System.out.println("\n##############################\n");

        withoutLombok();
    }



    private static void withLombok() {
        WithNonNull withLombok = new WithNonNull("answer");

        // 编译出错, 因为 name 字段被 @NonNull 修饰, 不可为空
        withLombok = new WithNonNull();
    }

    private static void withoutLombok() {
        WithoutNonNull withoutLombok = new WithoutNonNull("answer");
    }

}


@Data
class WithNonNull {
    @NonNull
    private String name;

    private String email;

    private String address;
}


@Data
class WithoutNonNull {
    private String name;

    private String email;

    private String address;

    public WithoutNonNull(String name) {
        this.name = name;
    }
}
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

public class AnswerAIL {

    public static void main(String[] args) {

//        withLombok();

        System.out.println("\n##############################\n");

        withoutLombok();
    }



    private static void withLombok() {
        WithNonNull withNonNull = new WithNonNull(null);
    }

    private static void withoutLombok() {
        WithoutNonNull withoutNonNull = new WithoutNonNull(null);
    }

}


class WithNonNull {
    @Getter
    @Setter
    private String name;

    public WithNonNull(@NonNull String name) {
        this.name = name;
    }
}


class WithoutNonNull {
    @Getter
    @Setter
    private String name;

    public WithoutNonNull(String name) {
        if (name == null) {
            throw new NullPointerException("name is marked @NonNull but is null");
        }
        this.name = name;
    }
}

@Cleanup

import lombok.Cleanup;
import java.io.*;

public class AnswerAIL {

    public static void main(String[] args) {

//        withLombok();

        System.out.println("\n##############################\n");

        withoutLombok();
    }



    private static void withLombok() {
        try {
            @Cleanup InputStream in = new FileInputStream("C:/ftpshare/answer.txt");
            @Cleanup OutputStream out = new FileOutputStream("C:/ftpshare/copy.txt");

            byte[] b = new byte[10000];
            while (true) {
                int r = in.read(b);
                if (r == -1) break;
                out.write(b, 0, r);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void withoutLombok() {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream("C:/ftpshare/answer.txt");

            out = new FileOutputStream("C:/ftpshare/copy.txt");

            byte[] b = new byte[10000];
            while (true) {
                int r = in.read(b);
                if (r == -1) break;
                out.write(b, 0, r);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

可以使用 @Cleanup 确保在代码执行路径退出当前作用域之前自动清理给定的资源。

可以使用@Cleanup 注释对任何局部变量声明进行注释。

@Getter and @Setter

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

public class AnswerAIL {

    public static void main(String[] args) {

        withLombok();

        System.out.println("\n##############################\n");

        withoutLombok();
    }



    private static void withLombok() {
        WithLombok withLombok = new WithLombok();
        withLombok.setName("answer");
        withLombok.setEmail("answer@ljm@163.com");

        System.out.println(withLombok.toString());
    }

    private static void withoutLombok() {
        WithoutLombok withoutLombok = new WithoutLombok();
        withoutLombok.setName("answer");
        withoutLombok.setEmail("answer@ljm@163.com");

        System.out.println(withoutLombok.toString());
    }

}


class WithLombok {
    @Getter
    @Setter
    private String name;

    @Setter(AccessLevel.PROTECTED)
    private String email;

    @Override
    public String toString() {
        return String.format("name[%s]\t\temail[%s]", name, email);
    }
}


class WithoutLombok {
    private String name;
    private String email;

    @Override
    public String toString() {
        return String.format("name[%s]\t\temail[%s]", name, email);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected void setEmail(String email) {
        this.email = email;
    }
}

@ToString

import lombok.ToString;

public class AnswerAIL {

    public static void main(String[] args) {

        Student student = new Student();

        System.out.println(student.toString());
    }

}


@ToString
class Person {
    private String name = "answer";

    private int sex = 1;
}


/**
 * # @ToString()
 *      Student(schoolName=ptwz)
 *
 * # @ToString(callSuper = true, includeFieldNames = false)
 *      Student(super=Person(name=answer, sex=1), ptwz)
 *
 * # @ToString(callSuper = true)
 *      Student(super=Person(name=answer, sex=1), schoolName=ptwz)
 * */
@ToString()
class Student extends Person {
    private String schoolName = "ptwz";

    // 重写 ToString 方法时, 排除掉 stuNo 字段
    @ToString.Exclude
    private String stuNo = "100000001";
}

@EqualsAndHashCode

import lombok.EqualsAndHashCode;

public class AnswerAIL {

}

@EqualsAndHashCode
class Person {
    private String name = "answer";

    private int sex = 1;
}


@EqualsAndHashCode(callSuper = false, of = {"schoolName"})
class Student extends Person {
    private String schoolName = "ptwz";

    // 此处编译会出错, 因为和 EqualsAndHashCode 中的 of 参数冲突
//    @EqualsAndHashCode.Exclude
    private String stuNo = "100000001";
}
  • 生成 equals(Object other)hashCode() 方法的实现
  • 它默认使用所有非静态,非瞬态字段
  • 可通过参数 @EqualsAndHashCode.Exclude 排除一些属性
  • 可通过参数 of 指定仅使用哪些属性
  • 默认仅使用该类中定义的属性且不调用父类的方法, 可通过设置 callSuper = false 来让其生成的方法中调用父类的方法

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

public class AnswerAIL {

    public static void main(String[] args) {
        Person person = Person.answerMethod("answer", 10);

        System.out.println(person.toString());
    }
}

// 定义静态方法的名称为 answerMethod, 修饰符为 public
@RequiredArgsConstructor(staticName = "answerMethod", access = AccessLevel.PUBLIC)
@ToString
class Person {
    @NonNull
    private String name;
    private final int age;
    private String email;

}

/* Output: Person(name=answer, age=10, email=null) */
  • RequiredArgsConstructor: 为所有 final 和 @NonNull 修饰的字段生成一个构造方法, 生成的构造方法是private,如何想要对外提供使用可以使用 staticName 选项生成一个static方法
  • NoArgsConstructor: 生成一个无参数的构造方法
  • AllArgsConstructor: 生成一个包含所有变量,同时如果变量使用了@NonNull修饰, 会进行是否为空的校验

@Data

import lombok.Data;
import lombok.NonNull;

public class AnswerAIL {

    public static void main(String[] args) {

        Person person = Person.newInstance("answer", "answer_ljm@163.com");
        System.out.println(person.toString());

    }

}

@Data(staticConstructor = "newInstance")
class Person {
    @NonNull
    private String name;
    @NonNull
    private String email;

}

/* Output: Person(name=answer, email=answer_ljm@163.com) */

说明: @Data 注释已经隐式的包含了 @Getter、@Setter、@ToString、@EqualSandHashCode 以及 @RequiredArgsConstructor 注释

@Value

https://projectlombok.org/features/Value

@Builder

https://projectlombok.org/features/Builder

@SneakyThrows

@SneakyThrows
public void method() {
    dataService.queryList();
}

// 反编译后代码
public void method() {
    try {
        this.dataService.queryList();
    } catch (Throwable var2) {
        throw var2;
    }
}

https://projectlombok.org/features/SneakyThrows

@Synchronized

https://projectlombok.org/features/Synchronized

@Getter(lazy=true)

https://projectlombok.org/features/GetterLazy

@Log (and friends)

@Log

import lombok.extern.java.Log;

// withLombok
@Log
public class AnswerAIL {
    // withoutLombok
//    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(AnswerAIL.class.getName());

    public static void main(String[] args) {

        log.severe("answer ai l");

        log.info("answer ai l");

    }

}

@Slf4j

import lombok.extern.slf4j.Slf4j;

// withLombok
@Slf4j
public class AnswerAIL {
    // withoutLombok
//    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AnswerAIL.class.getName());

    public static void main(String[] args) {

        log.info("answer ai l");

    }

}

@CommonsLog

import lombok.extern.apachecommons.CommonsLog;

// withLombok, 指定 topic 值, 默认为 类的全限定名
@CommonsLog(topic = "AnswerLog")
public class AnswerAIL {
    // withoutLombok, LogFactory.getLog(AnswerAIL.class);
//    private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("AnswerLog");

    public static void main(String[] args) {

        log.info("answer ai l");

    }

}

@Delegate

通过 @Delegate 注释实现代理模式

public interface IUserService {
    int insertUser();
    List<String> findUserNames();
    int updateUser();
    int deleteUser();
    // 注意此方法对应 UserMapper.findUserIds
    List<Long> queryUserIds();
}

@Service
public class UserServiceImpl implements IUserService {
    @lombok.experimental.Delegate
    private final UserMapper userMapper;

    @Autowired
    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public List<Long> queryUserIds() {
        return this.userMapper.findUserIds();
    }
}

public interface UserMapper {
    int insertUser();
    List<String> findUserNames();
    int updateUser();
    int deleteUser();
    List<Long> findUserIds();
}
public class UserServiceImpl {
    /**
     * 代理 userMapper 的所有方法(对外提供的方法名和代理的方法名一致)
     * */
    @Delegate
    private final UserMapper userMapper;

    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
}

@Accessors

链式风格

@Data
@Accessors(chain = true)
public class OrderDTO {
    private String orderNo;
    private Double orderAmt;
    private Byte orderStatus;
}

OrderDTO order = new OrderDTO();
order.setOrderNo("201912110001").setOrderAmt(12.542).setOrderStatus((byte)10);

它有三个选项:(以 name 成员变量为例)

  • fluent: 默认值是 false。如果是 false ,setter 生成的函数是 String setName(String name); 如果是 true, setter 是生成的是 User name(String name) ,返回的是 this,是种链式 Setter,同时 chain 会是 true。
  • chain: 默认值是 false。如果是 true,setter 生成的函数是 User setName(String name)。否则的是void setName(String name)
  • prefix: 比如成员变量是 gk_name,加上注解 @Accessors(prefix = “gk_”),生成的 Getter 和 Setter 中则没有 gk_ 前缀

 

附录 - References

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值