驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
lombok的奇技淫巧(邪恶..)
/  

lombok的奇技淫巧(邪恶..)

开篇

lombok这个插件非常好用,通过简单的注解就能省略很多冗余代码,常规的:@Data@Getter/@Setter@Slf4J这些基础的我就不写了,随便一百度就可以知道。

今天我们来讲讲几个冷门但是却好用的注解:

  • @NonNull
  • @Cleanup
  • @SneakyThrows
  • @Synchronized

NonNull

对方法的形参添加该字段,在编译后如果为null,就会抛出 NullPointerException

//成员方法参数加上@NonNull注解
public String getName(@NonNull Person p){
    return p.getName();
}

等效的写法如下

public String getName(Person p){
    if(p==null){
        throw new NullPointerException("person");
    }
    return p.getName();
}

Cleanup

学Java基础的IO流的时候,书中不止一次提到了对于Inputstream这类的流,使用后不要忘记关闭。

在Java7之前,关闭流要写一长串的冗余代码。

在Java8之后,通过try-with-resouce可以大大简化代码书写。

lombok引入了@Cleanup更加简单的处理该问题

public static void main(String[] args) throws Exception {
     @Cleanup 
     InputStream in = new FileInputStream(args[0]);
     @Cleanup 
     OutputStream out = new FileOutputStream(args[1]);
     byte[] b = new byte[1024];
     while (true) {
       int r = in.read(b);
       if (r == -1) break;
       out.write(b, 0, r);
     }
 }

Java7下的等效写法为:

public static void main(String[] args) throws Exception {
     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();
       }
    }
}

Java8下的等效写法

    public static void main(String[] args) throws Exception {
        try (InputStream in = new FileInputStream(args[0]);
             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);
            }
        }
    }

相比之下lombok的cleanup是不是更加简单了!?

对于初学者,笔者还是建议老老实实的用JDK7写一段时间,培养下”使用流要关闭流“这个观念。

SneakyThrows

Sneaky的中文意思是偷偷摸摸... 这个单词的发音是不是很像小老鼠的叫声,哈哈。

这个注解的作用是帮助我们抛出某类RuntimeException

    @SneakyThrows(UnsupportedEncodingException.class)
    public String utf8ToString(byte[] bytes) {
        return new String(bytes, "UTF-8");
    }

等效于

    public String utf8ToString(byte[] bytes) {
        try{
            return new String(bytes, "UTF-8");
        }catch(UnsupportedEncodingException uee){
            throw Lombok.sneakyThrow(uee);
        }
    }

请注意,JDK要求必须捕获的异常是没有办法处理的噢!

Synchronized

看这个就知道是加锁了,需要注意的是,静态方法和动态方法加的锁是不一样的!

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

等效于

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

总结

奇技淫巧到此为止了,希望大家在打好基础的情况下,再玩玩这些东西吧!

不积跬步,无以至千里。不积小流,无以成江海。