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

  • 相关阅读:
    随机选择
    Creating Apps With Material Design —— Defining Shadows and Clipping Views
    HDU 1853Cyclic Tour(网络流之最小费用流)
    053第502题
    【ThinkingInC++】64、重载new和delete,来模仿内存的分配
    Android设置里面默认存储器选项(default write disk)的实现
    Transparency Tutorial with C#
    ssh远程登录linux live系统
    JAVA把字符串当作表达式执行
    [Head First设计模式]生活中学设计模式——组合模式
  • 原文地址:https://www.cnblogs.com/junzi2099/p/8064976.html
Copyright © 2011-2022 走看看