七、Lombok注解详解(5)
12,@log
(1)该注解用在类上,可以省去从日志工厂生成日志对象这一步,直接进行日志记录,具体注解根据日志工具的不同而不同。不同的日志注解总结如下(上面是注解,下面是实际作用):
我们也可以在注解中使用 topic 来指定生成 log 对象时的类名。
1 @CommonsLog 2 private static final org.apache.commons.logging.Log log = 3 org.apache.commons.logging.LogFactory.getLog(LogExample.class); 4 5 @JBossLog 6 private static final org.jboss.logging.Logger log = 7 org.jboss.logging.Logger.getLogger(LogExample.class); 8 9 @Log 10 private static final java.util.logging.Logger log = 11 java.util.logging.Logger.getLogger(LogExample.class.getName()); 12 13 @Log4j 14 private static final org.apache.log4j.Logger log = 15 org.apache.log4j.Logger.getLogger(LogExample.class); 16 17 @Log4j2 18 private static final org.apache.logging.log4j.Logger log = 19 org.apache.logging.log4j.LogManager.getLogger(LogExample.class); 20 21 @Slf4j 22 private static final org.slf4j.Logger log = 23 org.slf4j.LoggerFactory.getLogger(LogExample.class); 24 25 @XSlf4j 26 private static final org.slf4j.ext.XLogger log = 27 org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
(2)下面是一个简单的使用样例:
1 // 使用注解 2 @Log 3 public class LogExample { 4 public static void main(String... args) { 5 log.error("Something's wrong here"); 6 } 7 } 8 9 // 不使用注解 10 public class LogExample { 11 private static final java.util.logging.Logger log = 12 java.util.logging.Logger.getLogger(LogExample.class.getName()); 13 14 public static void main(String... args) { 15 log.error("Something's wrong here"); 16 } 17 }
13,@Buinder
(1)builder 是现在比较推崇的一种构建值对象的方式。该描述符用于将类改造成 builder(建造者)模式,用在类、方法或者构造函数上。
1 package com.example.demo; 2 3 import lombok.Builder; 4 import lombok.Singular; 5 6 import java.util.Set; 7 8 @Builder 9 public class BuilderExample { 10 private String name; 11 private int age; 12 @Singular 13 private Set<String> occupations; 14 }
(2)上面相当于如下传统的 Java 代码:
1 package com.example.demo; 2 3 import java.util.Collection; 4 import java.util.Set; 5 6 public class BuilderExample { 7 private String name; 8 private int age; 9 private Set<String> occupations; 10 11 BuilderExample(String name, int age, Set<String> occupations) { 12 this.name = name; 13 this.age = age; 14 this.occupations = occupations; 15 } 16 17 public static BuilderExampleBuilder builder() { 18 return new BuilderExampleBuilder(); 19 } 20 21 public static class BuilderExampleBuilder { 22 private String name; 23 private int age; 24 private java.util.ArrayList<String> occupations; 25 26 BuilderExampleBuilder() { 27 } 28 29 public BuilderExampleBuilder name(String name) { 30 this.name = name; 31 return this; 32 } 33 34 public BuilderExampleBuilder age(int age) { 35 this.age = age; 36 return this; 37 } 38 39 public BuilderExampleBuilder occupation(String occupation) { 40 if (this.occupations == null) { 41 this.occupations = new java.util.ArrayList<String>(); 42 } 43 44 this.occupations.add(occupation); 45 return this; 46 } 47 48 public BuilderExampleBuilder occupations(Collection<? extends String> occupations) { 49 if (this.occupations == null) { 50 this.occupations = new java.util.ArrayList<String>(); 51 } 52 53 this.occupations.addAll(occupations); 54 return this; 55 } 56 57 public BuilderExampleBuilder clearOccupations() { 58 if (this.occupations != null) { 59 this.occupations.clear(); 60 } 61 62 return this; 63 } 64 65 public BuilderExample build() { 66 //complicated switch statement to produce a compact properly sized immutable set omitted 67 // go to https://projectlombok.org/features/Singular-snippet.html to see it. 68 Set<String> occupations = ...; 69 return new BuilderExample(name, age, occupations); 70 } 71 72 @java.lang.Override 73 public String toString() { 74 return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " 75 + this.age + ", occupations = " + this.occupations + ")"; 76 } 77 } 78 }
(3)下面是一个简单的测试样例:
1 BuilderExample be = BuilderExample.builder() 2 .name("hangge") 3 .age(123) 4 .occupation("ABC") 5 .occupation("DEF") 6 .build(); 7 8 return be.toString();
14,@SneakyThrows
(1)该注解用在方法上,可以将方法中的代码用 try-catch 语句包裹起来,捕获异常并在 catch 中用 Lombok.sneakyThrow(e) 把异常抛出。
(2)也可以使用 @SneakyThrows(Exception.class) 的形式指定抛出哪种异常。
1 // 使用注解 2 public class SneakyThrows implements Runnable { 3 @SneakyThrows(UnsupportedEncodingException.class) 4 public String utf8ToString(byte[] bytes) { 5 return new String(bytes, "UTF-8"); 6 } 7 8 @SneakyThrows 9 public void run() { 10 throw new Throwable(); 11 } 12 } 13 14 // 不使用注解 15 public class SneakyThrows implements Runnable { 16 public String utf8ToString(byte[] bytes) { 17 try{ 18 return new String(bytes, "UTF-8"); 19 }catch(UnsupportedEncodingException uee){ 20 throw Lombok.sneakyThrow(uee); 21 } 22 } 23 24 public void run() { 25 try{ 26 throw new Throwable(); 27 }catch(Throwable t){ 28 throw Lombok.sneakyThrow(t); 29 } 30 } 31 }
15,@Synchronized
该注解用在类方法或者实例方法上,效果和 synchronized 关键字相同,区别在于锁对象不同。对于类方法和实例方法,它俩区别在于:- synchronized 关键字的锁对象分别是“类的 class 对象”和“this 对象”
- @Synchronized 的锁对象分别是“私有静态 final 对象 lock”和“私有 final 对象 lock”。当然,也可以自己指定锁对象。
1 // 使用注解 2 public class Synchronized { 3 private final Object readLock = new Object(); 4 5 @Synchronized 6 public static void hello() { 7 System.out.println("world"); 8 } 9 10 @Synchronized 11 public int answerToLife() { 12 return 42; 13 } 14 15 @Synchronized("readLock") 16 public void foo() { 17 System.out.println("bar"); 18 } 19 } 20 21 // 不使用注解 22 public class Synchronized { 23 private static final Object $LOCK = new Object[0]; 24 private final Object $lock = new Object[0]; 25 private final Object readLock = new Object(); 26 27 public static void hello() { 28 synchronized($LOCK) { 29 System.out.println("world"); 30 } 31 } 32 33 public int answerToLife() { 34 synchronized($lock) { 35 return 42; 36 } 37 } 38 39 public void foo() { 40 synchronized(readLock) { 41 System.out.println("bar"); 42 } 43 } 44 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!