Lombok

Lombok

  • maven
  <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.16.18</version>
			--在编译阶段生效
          <scope>provided</scope>
    </dependency>
  • 原理
    通常解析类信息,使用反射,反射的方法局限性较大。首先,它必须定义@Retention为RetentionPolicy.RUNTIME,只能在运行时通过反射来获取注解值,使得运行时代码效率降低。
    而 JSR 269 之后我们可以在 Javac的编译期利用注解做这些事情,自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
    1)javac对源代码进行分析,生成语法
    2)运行过程中调用实现了"JSR 269 API"的处理类
    例如lombok中getter的处理类HandleGetter
    lombok的处理类基本遵循Handlexxx命名规范
    3)以完成它自己的逻辑,包括修改第一步骤得到的语法.
    4)javac使用修改后的语法,生成字节码文件

  • 部分注解/属性

@Getter
用于自动生成get方法。Boolean类型为is开头。

//标注在类,字段
@Target({ElementType.FIELD, ElementType.TYPE})
//只在源文件中保留,编译时执行
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
	//所生成get方法的访问权限
	lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
	//在生成的方法上增加注解
	//因为语法受到编译器版本的影响已经弃用
	AnyAnnotation[] onMethod() default {};
	@Deprecated
	@Retention(RetentionPolicy.SOURCE)
	@Target({})
	@interface AnyAnnotation {}
	//是否懒加载
	//现在需要对一个成员变量初始化,但是初始化过程复杂
	boolean lazy() default false;
}

java文件

@Getter(value = AccessLevel.PUBLIC)
public class User {
    private String userName;

    @Getter(value = AccessLevel.NONE)
    private String age;

    private boolean isAdmin;

    @Getter(lazy = true)
    private final String[] roleCode = selectRoleCode();

    private String[] selectRoleCode() {
        String[] result = new String[10000];
        for (int i = 0; i < result.length; i++) {
            result[i] = String.valueOf(Math.asin(i));
        }
        return result;
    }
}

class文件

public class User {
    private String userName;
    private String age;
    private boolean isAdmin;
    //考虑线程安全使用AtomicReference原子读写的对象
    private final AtomicReference<Object> roleCode = new AtomicReference();

    public User() {
    }

    private String[] selectRoleCode() {
        String[] result = new String[10000];
        for(int i = 0; i < result.length; ++i) {
            result[i] = String.valueOf(Math.asin((double)i));
        }
        return result;
    }

    public String getUserName() {
        return this.userName;
    }

    public boolean isAdmin() {
        return this.isAdmin;
    }

    public String[] getRoleCode() {
        Object value = this.roleCode.get();
        //线程同步锁双重检查
        //第一次n线程同时访问,外层检查value为空,多线程排队获取锁
        //第二次n线程同时方法,外层检查value不为空,多线程不再等待获取同步代码块锁,避免了不必要的排队现象
        if (value == null) {
            synchronized(this.roleCode) {
                value = this.roleCode.get();
                if (value == null) {
                    String[] actualValue = this.selectRoleCode();
                    value = actualValue == null ? this.roleCode : actualValue;
                    this.roleCode.set(value);
                }
            }
        }
        return (String[])((String[])(value == this.roleCode ? null : value));
    }
}

@Setter
自动生成set方法

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
	//所生成set方法的访问权限
	lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
	//为生成的set方法增加注解,弃用
	AnyAnnotation[] onMethod() default {};
	//为生成方法内的参数增加注解,弃用
	AnyAnnotation[] onParam() default {};
	@Deprecated
	@Retention(RetentionPolicy.SOURCE)
	@Target({})
	@interface AnyAnnotation {}
}

java文件

@Setter(value = AccessLevel.PUBLIC)
public class User {
    private String userName;

    @Setter(value = AccessLevel.NONE)
    private String age;

    private boolean isAdmin;
}

class文件

public class User {
    private String userName;
    private String age;
    private boolean isAdmin;

    public User() {
    }

    public void setUserName(final String userName) {
        this.userName = userName;
    }

    public void setAdmin(final boolean isAdmin) {
        this.isAdmin = isAdmin;
    }
}

@Data
自动生成成员变量的get/set/toString/hasCode/equals方法

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
	//生成一个静态方法,返回一个调用相应的构造方法产生的对象
	String staticConstructor() default "";
}

java文件

@Data(staticConstructor = "test")
public class User {
    private String userName;

    private String age;

    private boolean isAdmin;
}

class文件

public class User {
    private String userName;
    private String age;
    private boolean isAdmin;

    private User() {
    }

    public static User test() {
        return new User();
    }

    public String getUserName() {
        return this.userName;
    }

    public String getAge() {
        return this.age;
    }

    public boolean isAdmin() {
        return this.isAdmin;
    }

    public void setUserName(final String userName) {
        this.userName = userName;
    }

    public void setAge(final String age) {
        this.age = age;
    }

    public void setAdmin(final boolean isAdmin) {
        this.isAdmin = isAdmin;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof User)) {
            return false;
        } else {
            User other = (User)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                label39: {
                    Object this$userName = this.getUserName();
                    Object other$userName = other.getUserName();
                    if (this$userName == null) {
                        if (other$userName == null) {
                            break label39;
                        }
                    } else if (this$userName.equals(other$userName)) {
                        break label39;
                    }

                    return false;
                }

                Object this$age = this.getAge();
                Object other$age = other.getAge();
                if (this$age == null) {
                    if (other$age != null) {
                        return false;
                    }
                } else if (!this$age.equals(other$age)) {
                    return false;
                }

                if (this.isAdmin() != other.isAdmin()) {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $userName = this.getUserName();
        int result = result * 59 + ($userName == null ? 43 : $userName.hashCode());
        Object $age = this.getAge();
        result = result * 59 + ($age == null ? 43 : $age.hashCode());
        result = result * 59 + (this.isAdmin() ? 79 : 97);
        return result;
    }

    public String toString() {
        return "User(userName=" + this.getUserName() + ", age=" + this.getAge() + ", isAdmin=" + this.isAdmin() + ")";
    }
}

@ToString
自动生成toString()方法

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ToString {
	//打印是否包含字段名称
	boolean includeFieldNames() default true;
	//是否只通过标记字段来标记使用的字段
	boolean onlyExplicitlyIncluded() default false;
	//是否toString方法体内会带上超类的toString方法
	boolean callSuper() default false;
	//剔除字段,或者注解变量标记为剔除字段
	String[] exclude() default {};
	@Target(ElementType.FIELD)
	@Retention(RetentionPolicy.SOURCE)
	public @interface Exclude {}
	//包含字段,或者注解变量标记为包含字段
	String[] of() default {};
	@Target({ElementType.FIELD, ElementType.METHOD})
	@Retention(RetentionPolicy.SOURCE)
	public @interface Include {}
}

java文件

@ToString
public class Example {
private String name;
    private Shape shape = new Square(5, 10);
    private String[] tags = new String[]{"1", "2", "3"};
    /**
     * 标记 @ToString.Exclude
     * toString方法不包含此字段
     */
    @ToString.Exclude
    private int id;
	@ToString(callSuper = true, includeFieldNames = false)
    public static class Square extends Shape {

        private final int width, height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }
    }

    public static class Shape {

        @Override
        public String toString() {
            return "Shape[" + this.hashCode() + "]";
        }

    }
}

class文件

public class Example {
    private String name;
    private Example.Shape shape = new Example.Square(5, 10);
    private String[] tags = new String[]{"1", "2", "3"};
    private int id;

    public Example() {
    }

    public String toString() {
        return "Example(name=" + this.name + ", shape=" + this.shape + ", tags=" + Arrays.deepToString(this.tags) + ")";
    }

    public static class Shape {
        public Shape() {
        }

        public String toString() {
            return "Shape[" + this.hashCode() + "]";
        }
    }

    public static class Square extends Example.Shape {
        private final int width;
        private final int height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }

        public String toString() {
            return "Example.Square(super=" + super.toString() + ", " + this.width + ", " + this.height + ")";
        }
    }
}

结果
Example(name=null, shape=Example.Square(super=Shape[471910020], 5, 10), tags=[1, 2, 3])

@EqualsAndHashCode
自动生成Equals方法和hashcode方法

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
	//剔除字段,或者注解变量标记为剔除字段
	String[] exclude() default {};
	@Target(ElementType.FIELD)
	@Retention(RetentionPolicy.SOURCE)
	public @interface Exclude {}
	//包含字段,或者注解变量标记为包含字段
	String[] of() default {};
	@Target({ElementType.FIELD, ElementType.METHOD})
	@Retention(RetentionPolicy.SOURCE)
	public @interface Include {}
}

@SneakyThrows
自动生成try-catch代码块抛出异常

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface SneakyThrows {
//跑出的错误类型
	Class<? extends Throwable>[] value() default java.lang.Throwable.class;
	
}

java文件

public class Test {

    @SneakyThrows
    public void doSomething(){
        System.out.println("hello world...");
    }
}

class文件

public class Test {
    public Test() {
    }

    public void doSomething() {
        try {
            System.out.println("hello world...");
        } catch (Throwable var2) {
            throw var2;
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值