zoukankan      html  css  js  c++  java
  • java工具jar包—Lombok

    如何引入

    maven工程,直接引入lombok的jar依赖即可:

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.18</version>
    </dependency>

    val

    我们定义一个常量都会这样写:

    import java.util.ArrayList;  
    import java.util.HashMap;  
    import java.util.Map;  
      
    public class ValExample {  
      public String example() {  
        final ArrayList<String> example = new ArrayList<String>();  
        example.add("Hello, World!");  
        final String foo = example.get(0);  
        return foo.toLowerCase();  
      }  
        
      public void example2() {  
        final HashMap<Integer, String> map = new HashMap<Integer, String>();  
        map.put(0, "zero");  
        map.put(5, "five");  
        for (final Map.Entry<Integer, String> entry : map.entrySet()) {  
          System.out.printf("%d: %s
    ", entry.getKey(), entry.getValue());  
        }  
      }  
    }  

      但是, 自从有了Lombok, final + 类型 这种复杂的定义方式不再需要了。

    import java.util.ArrayList;  
    import java.util.HashMap;  
    import lombok.val;  
      
    public class ValExample {  
      public String example() {  
        val example = new ArrayList<String>();  
        example.add("Hello, World!");  
        val foo = example.get(0);  
        return foo.toLowerCase();  
      }  
        
      public void example2() {  
        val map = new HashMap<Integer, String>();  
        map.put(0, "zero");  
        map.put(5, "five");  
        for (val entry : map.entrySet()) {  
          System.out.printf("%d: %s
    ", entry.getKey(), entry.getValue());  
        }  
      }  
    }  

    @NotNull

    对比下面两端代码:

    import lombok.NonNull;  
      
    public class NonNullExample extends Something {  
      private String name;  
        
      public NonNullExample(@NonNull Person person) {  
        super("Hello");  
        this.name = person.getName();  
      }  
    } 
    import lombok.NonNull;  
      
    public class NonNullExample extends Something {  
      private String name;  
        
      public NonNullExample(Person person) {  
        super("Hello");  
        if (person == null) {  
          throw new NullPointerException("person");  
        }  
        this.name = person.getName();  
      }  
    }

    估计看过guava代码的应该都看到过这种annotation。其实NotNull包括了两种Exception,有一个可选的annotation参数,通过exceptionType,可以决定当前位置是用IllegalArgumentException还是NPE,当然默认值就是NPE了。在Lombok中有一个好处就是如果使用了如@Data这样的Lombok annotation,也会默认触发@NotNull 的, 同时如果把@NotNull加到了原始类型上,你将收获一个warning。

    @Cleanup

    使用前:

    import java.io.*;  
      
    public class CleanupExample {  
      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();  
          }  
        }  
      }  
    }

    使用后: 

    import lombok.Cleanup;  
    import java.io.*;  
      
    public class CleanupExample {  
      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[10000];  
        while (true) {  
          int r = in.read(b);  
          if (r == -1) break;  
          out.write(b, 0, r);  
        }  
      }  
    } 

    单单从代码的行数上面就可以知道已经精简了不少,同时,代码的可读性也进一步提高。从代码中我们可以容易的看出,@Cleanup的作用就是在当前变量不在有效范围内的时候,对其进行自动的资源回收。在Java中的Stream上使用Cleanup Annotation,就是对其调用close方法。

     但是,请大家注意,Cleanup 存在一个小问题:

    官网给出了提示,如果你的代码中出现了异常,那么会触发cleanup方法抛出异常,导致把原始异常吞掉,这样就导致你在上层不知道发生了什么事情,这个事情很严重啊,但是如果说你是在调用close方法的时候出了异常,那么Cleanup这个annotation是不会把异常吞掉的。 同时,官网也指出,作者也没有找到更好的方式去解决这个问题,如果他们找到了会立刻fix这个问题,否则也就只能等待Java 有可能在Update的时候出现新的解决方案。

    @Getter, @Setter

    想必你一定为写这样的代码而苦恼:

    public class GetterSetterExample {  
    
      private int age = 10;  
      
      private String name;  
        
      @Override public String toString() {  
        return String.format("%s (age: %d)", name, age);  
      }  
        
      public int getAge() {  
        return age;  
      }  
        
      public void setAge(int age) {  
        this.age = age;  
      }  
        
      protected void setName(String name) {  
        this.name = name;  
      }  
    } 

     那么这两个annotation到底能干什么呢?

    import lombok.AccessLevel;  
    import lombok.Getter;  
    import lombok.Setter;  
      
    public class GetterSetterExample {  
    
      @Getter @Setter private int age = 10;  
        
      @Setter(AccessLevel.PROTECTED) private String name;  
        
      @Override public String toString() {  
        return String.format("%s (age: %d)", name, age);  
      }  
    }  

     如果没有设置AccessLevel属性,则生成的默认方法为public的。如果想要使get,set方法不生效,则可以使用一个特殊的AccessLevel 选项 “NONE”。

    同样给大家一点小的建议:

    在使用的时候如果当前bean中包括某个方法,恰好要和生成的方法名字一样,则Lombok不会再处理生成,无论是不是两个函数的方法是重载。例如:如果类中包含String get(String anme), 则不会再为bean生成一个新的方法。

    @ToString

    我们的代码经常这样: 

    import java.util.Arrays;  
      
    public class ToStringExample {  
      private static final int STATIC_VAR = 10;  
      private String name;  
      private Shape shape = new Square(5, 10);  
      private String[] tags;  
      private int id;  
        
      public String getName() {  
        return this.getName();  
      }  
        
      public static class Square extends Shape {  
        private final int width, height;  
          
        public Square(int width, int height) {  
          this.width = width;  
          this.height = height;  
        }  
          
        @Override public String toString() {  
          return "Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";  
        }  
      }  
        
      @Override public String toString() {  
        return "ToStringExample(" + this.getName() + ", " + this.shape + ", " + Arrays.deepToString(this.tags) + ")";  
      }  
    }  

     其实,我们的代码可以这样:

    import lombok.ToString;  
      
    @ToString(exclude="id")  
    public class ToStringExample {  
      private static final int STATIC_VAR = 10;  
      private String name;  
      private Shape shape = new Square(5, 10);  
      private String[] tags;  
      private int id;  
        
      public String getName() {  
        return this.getName();  
      }  
        
      @ToString(callSuper=true, includeFieldNames=true)  
      public static class Square extends Shape {  
        private final int width, height;  
          
        public Square(int width, int height) {  
          this.width = width;  
          this.height = height;  
        }  
      }  
    }  

     这样的方便方式节省了好多拼接字符串的功夫。

     lombok.toString.includeFieldNames = [true | false] (default: true)是否包含field的信息,如果值为true ,则可以在toString方法中给出field 的name。

    lombok.toString.doNotUseGetters = [true | false] (default: false)如果值为true,则Lombok会直接获取field 而不是通过get方法获取值。

    @EqualsAndHashCode

    实现equals, hashCode方法是在编程生活中再常见不过的一个东西了,那么自然@EqualsAndHashCode 这个annotation就成为了一个非常方便的工具。默认情况下,被这个annotation标注的class会用到除了 static,transient修饰的所有属性作为判断标准,当然和之前的annotation一样,可是使用exclude选项除掉不想要的属性。也可以通过callSuper包含父类的equals 和 hashCode。 当然如果你的class 没有继承任何其他的class,你却写了callSuper,那么会收获一个编译报错。

    你只要这样用:

    import lombok.EqualsAndHashCode;  
      
    @EqualsAndHashCode(exclude={"id", "shape"})  
    public class EqualsAndHashCodeExample {  
      private transient int transientVar = 10;  
      private String name;  
      private double score;  
      private Shape shape = new Square(5, 10);  
      private String[] tags;  
      private int id;  
        
      public String getName() {  
        return this.name;  
      }  
        
      @EqualsAndHashCode(callSuper=true)  
      public static class Square extends Shape {  
        private final int width, height;  
          
        public Square(int width, int height) {  
          this.width = width;  
          this.height = height;  
        }  
      }  
    }  

     就可以得到这样的效果:

    import java.util.Arrays;  
      
    public class EqualsAndHashCodeExample {  
      private transient int transientVar = 10;  
      private String name;  
      private double score;  
      private Shape shape = new Square(5, 10);  
      private String[] tags;  
      private int id;  
        
      public String getName() {  
        return this.name;  
      }  
        
      @Override public boolean equals(Object o) {  
        if (o == this) return true;  
        if (!(o instanceof EqualsAndHashCodeExample)) return false;  
        EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;  
        if (!other.canEqual((Object)this)) return false;  
        if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;  
        if (Double.compare(this.score, other.score) != 0) return false;  
        if (!Arrays.deepEquals(this.tags, other.tags)) return false;  
        return true;  
      }  
        
      @Override public int hashCode() {  
        final int PRIME = 59;  
        int result = 1;  
        final long temp1 = Double.doubleToLongBits(this.score);  
        result = (result*PRIME) + (this.name == null ? 0 : this.name.hashCode());  
        result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));  
        result = (result*PRIME) + Arrays.deepHashCode(this.tags);  
        return result;  
      }  
        
      protected boolean canEqual(Object other) {  
        return other instanceof EqualsAndHashCodeExample;  
      }  
        
      public static class Square extends Shape {  
        private final int width, height;  
          
        public Square(int width, int height) {  
          this.width = width;  
          this.height = height;  
        }  
          
        @Override public boolean equals(Object o) {  
          if (o == this) return true;  
          if (!(o instanceof Square)) return false;  
          Square other = (Square) o;  
          if (!other.canEqual((Object)this)) return false;  
          if (!super.equals(o)) return false;  
          if (this.width != other.width) return false;  
          if (this.height != other.height) return false;  
          return true;  
        }  
          
        @Override public int hashCode() {  
          final int PRIME = 59;  
          int result = 1;  
          result = (result*PRIME) + super.hashCode();  
          result = (result*PRIME) + this.width;  
          result = (result*PRIME) + this.height;  
          return result;  
        }  
          
        protected boolean canEqual(Object other) {  
          return other instanceof Square;  
        }  
      }  
    }  

    这就是Lombok的优势所在。几个需要注意的点是,对于Array类型的变量,如果需要进行equals和hashCode的时候需要调用工具类的Arrays中的deepHashCode, deepEquals完成比较。

    Constructor

    在Lombok中,生成构造方法的annotation一共有三个,@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsContructor。使用这三个annotation来完成项目中对于不同构造方法的需求。

     @NoArgsConstructor : 生成一个无参数的构造方法,这个annotation在与其他的annotation配合起来使用的时候更加能凸显出他的重要性,例如在使用hibernate这种框架的时候,如果有一个有参数的构造方法的时候,NoArgsConstructor会展示出他的作用。

     @RequiredArgsConstructor: 会生成一个包含常量,和标识了NotNull的变量 的构造方法。生成的构造方法是private,如何想要对外提供使用可以使用staticName选项生成一个static方法。

     @AllArgsContructor:  会生成一个包含所有变量,同时如果变量使用了NotNull annotation , 会进行是否为空的校验。

    我们来看一下官方给出的一个例子:

    import lombok.AccessLevel;  
    import lombok.RequiredArgsConstructor;  
    import lombok.AllArgsConstructor;  
    import lombok.NonNull;  
      
    @RequiredArgsConstructor(staticName = "of")  
    @AllArgsConstructor(access = AccessLevel.PROTECTED)  
    public class ConstructorExample<T> {  
      private int x, y;  
      @NonNull private T description;  
        
      @NoArgsConstructor  
      public static class NoArgsExample {  
        @NonNull private String field;  
      }  
    } 

    上面的例子用Java代码翻译一下就是:

    public class ConstructorExample<T> {  
      private int x, y;  
      @NonNull private T description;  
        
      private ConstructorExample(T description) {  
        if (description == null) throw new NullPointerException("description");  
        this.description = description;  
      }  
        
      public static <T> ConstructorExample<T> of(T description) {  
        return new ConstructorExample<T>(description);  
      }  
        
      @java.beans.ConstructorProperties({"x", "y", "description"})  
      protected ConstructorExample(int x, int y, T description) {  
        if (description == null) throw new NullPointerException("description");  
        this.x = x;  
        this.y = y;  
        this.description = description;  
      }  
        
      public static class NoArgsExample {  
        @NonNull private String field;  
          
        public NoArgsExample() {  
        }  
      }  
    }  

     如果是@AllArgsConstructor 在生成的构造函数上会生成一@ConstructorProperties 的Java annotation, 当然也可以通过将suppressConstructorProperties 设置为true来禁用@ConstructorProperties 。 如果你知道@ConstructorProperties 是干什么用的,那么一定就知道@NoArgsConstructor为什么没有这个配置参数了。 

    提示一点:@ConstructorProperties 只能用在JDK 6 中。

    @Data,@Value

    作为之前介绍几个annotation的一个统称,可谓整理了方便,@Data直接修饰POJO or beans, getter所有的变量,setter所有不为final的变量。如果你不需要默认的生成方式,直接填写你需要的annotation的就可以了。默认生成的所有的annotation都是public的,如果需要不同权限修饰符可以使用AccessLevel.NONE选项。当然@Data 也可以使用staticConstructor选项生成一个静态方法。
    使用Data annotation可以简便的完成自己想要的内容:
    import lombok.AccessLevel;  
    import lombok.Setter;  
    import lombok.Data;  
    import lombok.ToString;  
      
    @Data public class DataExample {  
      private final String name;  
      @Setter(AccessLevel.PACKAGE) private int age;  
      private double score;  
      private String[] tags;  
        
      @ToString(includeFieldNames=true)  
      @Data(staticConstructor="of")  
      public static class Exercise<T> {  
        private final String name;  
        private final T value;  
      }  
    }

    使用后:

    import java.util.Arrays;  
      
    public class DataExample {  
      private final String name;  
      private int age;  
      private double score;  
      private String[] tags;  
        
      public DataExample(String name) {  
        this.name = name;  
      }  
        
      public String getName() {  
        return this.name;  
      }  
        
      void setAge(int age) {  
        this.age = age;  
      }  
        
      public int getAge() {  
        return this.age;  
      }  
        
      public void setScore(double score) {  
        this.score = score;  
      }  
        
      public double getScore() {  
        return this.score;  
      }  
        
      public String[] getTags() {  
        return this.tags;  
      }  
        
      public void setTags(String[] tags) {  
        this.tags = tags;  
      }  
        
      @Override public String toString() {  
        return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";  
      }  
        
      protected boolean canEqual(Object other) {  
        return other instanceof DataExample;  
      }  
        
      @Override public boolean equals(Object o) {  
        if (o == this) return true;  
        if (!(o instanceof DataExample)) return false;  
        DataExample other = (DataExample) o;  
        if (!other.canEqual((Object)this)) return false;  
        if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;  
        if (this.getAge() != other.getAge()) return false;  
        if (Double.compare(this.getScore(), other.getScore()) != 0) return false;  
        if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;  
        return true;  
      }  
        
      @Override public int hashCode() {  
        final int PRIME = 59;  
        int result = 1;  
        final long temp1 = Double.doubleToLongBits(this.getScore());  
        result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());  
        result = (result*PRIME) + this.getAge();  
        result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));  
        result = (result*PRIME) + Arrays.deepHashCode(this.getTags());  
        return result;  
      }  
        
      public static class Exercise<T> {  
        private final String name;  
        private final T value;  
          
        private Exercise(String name, T value) {  
          this.name = name;  
          this.value = value;  
        }  
          
        public static <T> Exercise<T> of(String name, T value) {  
          return new Exercise<T>(name, value);  
        }  
          
        public String getName() {  
          return this.name;  
        }  
          
        public T getValue() {  
          return this.value;  
        }  
          
        @Override public String toString() {  
          return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";  
        }  
          
        protected boolean canEqual(Object other) {  
          return other instanceof Exercise;  
        }  
          
        @Override public boolean equals(Object o) {  
          if (o == this) return true;  
          if (!(o instanceof Exercise)) return false;  
          Exercise<?> other = (Exercise<?>) o;  
          if (!other.canEqual((Object)this)) return false;  
          if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;  
          if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;  
          return true;  
        }  
          
        @Override public int hashCode() {  
          final int PRIME = 59;  
          int result = 1;  
          result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());  
          result = (result*PRIME) + (this.getValue() == null ? 0 : this.getValue().hashCode());  
          return result;  
        }  
      }  
    }

     与@Data相对应的@Value, 两个annotation的主要区别就是如果变量不加@NonFinal ,@Value会给所有的弄成final的。当然如果是final的话,就没有set方法了。 

    import lombok.AccessLevel;  
    import lombok.experimental.NonFinal;  
    import lombok.experimental.Value;  
    import lombok.experimental.Wither;  
    import lombok.ToString;  
      
    @Value public class ValueExample {  
      String name;  
      @Wither(AccessLevel.PACKAGE) @NonFinal int age;  
      double score;  
      protected String[] tags;  
        
      @ToString(includeFieldNames=true)  
      @Value(staticConstructor="of")  
      public static class Exercise<T> {  
        String name;  
        T value;  
      }  
    }  

     使用后:

    import java.util.Arrays;  
      
    public final class ValueExample {  
      private final String name;  
      private int age;  
      private final double score;  
      protected final String[] tags;  
        
      @java.beans.ConstructorProperties({"name", "age", "score", "tags"})  
      public ValueExample(String name, int age, double score, String[] tags) {  
        this.name = name;  
        this.age = age;  
        this.score = score;  
        this.tags = tags;  
      }  
        
      public String getName() {  
        return this.name;  
      }  
        
      public int getAge() {  
        return this.age;  
      }  
        
      public double getScore() {  
        return this.score;  
      }  
        
      public String[] getTags() {  
        return this.tags;  
      }  
        
      @java.lang.Override  
      public boolean equals(Object o) {  
        if (o == this) return true;  
        if (!(o instanceof ValueExample)) return false;  
        final ValueExample other = (ValueExample)o;  
        final Object this$name = this.getName();  
        final Object other$name = other.getName();  
        if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;  
        if (this.getAge() != other.getAge()) return false;  
        if (Double.compare(this.getScore(), other.getScore()) != 0) return false;  
        if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;  
        return true;  
      }  
        
      @java.lang.Override  
      public int hashCode() {  
        final int PRIME = 59;  
        int result = 1;  
        final Object $name = this.getName();  
        result = result * PRIME + ($name == null ? 0 : $name.hashCode());  
        result = result * PRIME + this.getAge();  
        final long $score = Double.doubleToLongBits(this.getScore());  
        result = result * PRIME + (int)($score >>> 32 ^ $score);  
        result = result * PRIME + Arrays.deepHashCode(this.getTags());  
        return result;  
      }  
        
      @java.lang.Override  
      public String toString() {  
        return "ValueExample(name=" + getName() + ", age=" + getAge() + ", score=" + getScore() + ", tags=" + Arrays.deepToString(getTags()) + ")";  
      }  
        
      ValueExample withAge(int age) {  
        return this.age == age ? this : new ValueExample(name, age, score, tags);  
      }  
        
      public static final class Exercise<T> {  
        private final String name;  
        private final T value;  
          
        private Exercise(String name, T value) {  
          this.name = name;  
          this.value = value;  
        }  
          
        public static <T> Exercise<T> of(String name, T value) {  
          return new Exercise<T>(name, value);  
        }  
          
        public String getName() {  
          return this.name;  
        }  
          
        public T getValue() {  
          return this.value;  
        }  
          
        @java.lang.Override  
        public boolean equals(Object o) {  
          if (o == this) return true;  
          if (!(o instanceof ValueExample.Exercise)) return false;  
          final Exercise<?> other = (Exercise<?>)o;  
          final Object this$name = this.getName();  
          final Object other$name = other.getName();  
          if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;  
          final Object this$value = this.getValue();  
          final Object other$value = other.getValue();  
          if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;  
          return true;  
        }  
          
        @java.lang.Override  
        public int hashCode() {  
          final int PRIME = 59;  
          int result = 1;  
          final Object $name = this.getName();  
          result = result * PRIME + ($name == null ? 0 : $name.hashCode());  
          final Object $value = this.getValue();  
          result = result * PRIME + ($value == null ? 0 : $value.hashCode());  
          return result;  
        }  
          
        @java.lang.Override  
        public String toString() {  
          return "ValueExample.Exercise(name=" + getName() + ", value=" + getValue() + ")";  
        }  
      }  
    }

    @Sychronized

    @Sychronized 是一个处理线程安全问题的annotation, 他的使用方法和关键字 synchronized比较类似,但是有一些不同点就是,关键字synchronized是锁定当前对象(this指针) , 而@Synchronized则会锁定一个private的常量。如果当前类中没有这个常量,就会自动生成一个。

    import lombok.Synchronized;  
      
    public class SynchronizedExample {  
      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");  
      }  
    }  

     如果当前锁定的方法是一个静态的方法的话,会自动生成一个静态常量,如果是一个普通方法的话会生成一个普通常量,类型为Object 

    public class SynchronizedExample {  
      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");  
        }  
      }  
    } 

    @Getter(lazy=true)

    最后终于到了一个高级点的annotation的用法了,使用lazy版的getter annotation, 会提高代码效率,同时由Lombok帮助你管理线程安全问题,大可放心。先看一段代码: 

    import lombok.Getter;  
      
    public class GetterLazyExample {  
      @Getter(lazy=true) private final double[] cached = expensive();  
        
      private double[] expensive() {  
        double[] result = new double[1000000];  
        for (int i = 0; i < result.length; i++) {  
          result[i] = Math.asin(i);  
        }  
        return result;  
      }  
    }


    使用了getter这个annotation可以在实际使用到cached的时候生成cached,同时,Lombok会自动去管理线程安全的问题,不会存在重复赋值的问题。

    Log

    Lombok封装了许多主流的Log库,提供了一系列关于Log 的annotation。下面就是所有的annotation会代表哪些特定的类 :

    @CommonsLog  
    Creates private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);  
    @Log  
    Creates private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());  
    @Log4j  
    Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);  
    @Log4j2  
    Creates private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);  
    @Slf4j  
    Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);  
    @XSlf4j  
    Creates private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

    就用其中的几个举个例子吧:

    import lombok.extern.java.Log;  
    import lombok.extern.slf4j.Slf4j;  
      
    @Log  
    public class LogExample {  
        
      public static void main(String... args) {  
        log.error("Something's wrong here");  
      }  
    }  
      
    @Slf4j  
    public class LogExampleOther {  
        
      public static void main(String... args) {  
        log.error("Something else is wrong here");  
      }  
    }  
      
    @CommonsLog(topic="CounterLog")  
    public class LogExampleCategory {  
      
      public static void main(String... args) {  
        log.error("Calling the 'CounterLog' with a message");  
      }  
    }


    翻译一下,代码如下:

    public class LogExample {  
      private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());  
        
      public static void main(String... args) {  
        log.error("Something's wrong here");  
      }  
    }  
      
    public class LogExampleOther {  
      private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);  
        
      public static void main(String... args) {  
        log.error("Something else is wrong here");  
      }  
    }  
      
    public class LogExampleCategory {  
      private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");  
      
      public static void main(String... args) {  
        log.error("Calling the 'CounterLog' with a message");  
      }  
    }


    @SneakyThrows

    @SneakyThrows的用法比较简单,其实就是对于异常的一个整理,将checked exception 看做unchecked exception, 不处理,直接扔掉。 减少了到处写catch的不便利性。比如在线程中,catch所有异常,再比如在一些不太可能发生异常的地方,但是你又必须cache checked exception的地方使用这个annotation会显得代码比较规整,易读。或许也会显得高大上一点吧

    import lombok.SneakyThrows;
    
    public class SneakyThrowsExample implements Runnable {
       @SneakyThrows(UnsupportedEncodingException.class)
       public String utf8ToString(byte[] bytes) {
         return new String(bytes, &quot;UTF-8&quot;);
       }
       
       @SneakyThrows
       public void run() {
         throw new Throwable();
       }
    }
    import lombok.Lombok;
    
    public class SneakyThrowsExample implements Runnable {
       public String utf8ToString(byte[] bytes) {
         try {
           return new String(bytes, &quot;UTF-8&quot;);
         } catch (UnsupportedEncodingException e) {
           throw Lombok.sneakyThrow(e);
         }
       }
       
       public void run() {
         try {
           throw new Throwable();
         } catch (Throwable t) {
           throw Lombok.sneakyThrow(t);
         }
       }
    }

    参考资料

    http://himichaelchu.iteye.com/category/324280

  • 相关阅读:
    Android开发总结
    LeakCanary原理分析
    机器学习
    Kivy 中文教程 实例入门 简易画板 (Simple Paint App):2. 实现绘图功能
    Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 3. 循环
    Kivy 中文教程 实例入门 简易画板 (Simple Paint App):1. 自定义窗口部件 (widget)
    Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 2. 变量
    Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 1. 神秘朋友
    Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 0. 准备工作
    远程显示(操作) 服务器 GUI 程序(图形化界面) (基于 X11 Forwarding + Centos + MobaXterm)
  • 原文地址:https://www.cnblogs.com/junzi2099/p/8064976.html
Copyright © 2011-2022 走看看