Java常用注解详解:从基础到高级的全面解析与实战应用
一、基础注解
(一)@Override
- 作用
- 用于方法声明上,表示该方法覆盖了父类中的同名方法。它主要用来提醒开发者,确保方法的签名与父类中的方法完全一致。如果方法的签名不匹配,编译器会报错。
- 例如,当我们在子类中重写父类的
toString()
方法时,使用@Override
可以明确地告诉编译器我们的意图,避免因拼写错误或其他问题导致无法正确覆盖。 -
@Override public String toString() { return "This is an overridden toString method."; }
- 优势
- 增强代码的可读性,让其他开发者一眼就能看出该方法是覆盖父类的方法。
- 编译器会进行检查,避免错误地覆盖了其他方法,减少潜在的错误。
(二)@Deprecated
- 作用
- 用于标记类、方法或字段已经被废弃,不推荐使用。当其他开发者使用被标记为
@Deprecated
的元素时,编译器会发出警告。 - 例如,如果一个旧的API方法被新的方法替代,我们可以使用
@Deprecated
来标记旧的方法。 -
@Deprecated public void oldMethod() { System.out.println("This method is deprecated."); }
- 用于标记类、方法或字段已经被废弃,不推荐使用。当其他开发者使用被标记为
- 优势
- 提供明确的提示,告知其他开发者该元素可能在未来版本中被移除,建议使用替代方案。
- 有助于维护代码的现代化,避免使用过时的功能。
(三)@SuppressWarnings
- 作用
- 用于抑制编译器警告。当代码中存在某些不可避免的警告(如未使用的变量、类型安全警告等),可以通过
@SuppressWarnings
注解来告诉编译器忽略这些警告。 - 例如,当我们使用泛型时,可能会出现类型安全警告,可以通过指定
"unchecked"
来抑制这些警告。 -
@SuppressWarnings("unchecked") public void example() { List list = new ArrayList(); list.add("Hello"); }
- 用于抑制编译器警告。当代码中存在某些不可避免的警告(如未使用的变量、类型安全警告等),可以通过
- 优势
- 让代码更加整洁,避免不必要的警告干扰开发者的注意力。
- 但需要注意的是,过度使用
@SuppressWarnings
可能会掩盖潜在的问题,因此应该谨慎使用。
二、Java SE自带注解
(一)@FunctionalInterface
- 作用
- 用于标记一个接口是函数式接口。函数式接口是指只有一个抽象方法的接口,它可以与Lambda表达式一起使用。
- 例如,
Runnable
接口就是一个函数式接口,因为它只有一个run()
方法。 -
@FunctionalInterface public interface SimpleFunctionalInterface { void execute(); }
- 优势
- 明确地标识接口的用途,让其他开发者知道该接口可以与Lambda表达式配合使用。
- 编译器会进行检查,确保被标记为
@FunctionalInterface
的接口确实只有一个抽象方法,避免错误的定义。
(二)@SafeVarargs
- 作用
- 用于标记一个方法的可变参数是安全的,不会引发类型安全问题。在Java中,可变参数可能会导致类型安全警告,尤其是在泛型场景下。
- 例如,当我们在一个泛型方法中使用可变参数时,可能会收到类型安全警告。通过
@SafeVarargs
注解,可以告诉编译器这些可变参数是安全的。 -
@SafeVarargs public static <T> void printAll(T... args) { for (T arg : args) { System.out.println(arg); } }
- 优势
- 抑制与可变参数相关的类型安全警告,让代码更加简洁。
- 但需要确保方法的实现确实不会引发类型安全问题,否则可能会导致运行时错误。
(三)@Repeatable
- 作用
- 用于标记一个注解可以重复使用。在Java 8之前,一个注解只能在一个元素上使用一次。通过
@Repeatable
注解,可以让一个注解在同一个元素上多次使用。 - 例如,我们可以定义一个
@Tag
注解,并通过@Repeatable
让其可以在一个类上多次使用。 -
@Repeatable(Tags.class) public @interface Tag { String value(); } public @interface Tags { Tag[] value(); } @Tag("first") @Tag("second") public class ExampleClass { }
- 用于标记一个注解可以重复使用。在Java 8之前,一个注解只能在一个元素上使用一次。通过
- 优势
- 提供了更灵活的注解使用方式,可以为同一个元素添加多个相同类型的注解。
- 但需要注意的是,重复注解需要通过一个容器注解来实现,如上面的
Tags
注解。
三、Java EE(Jakarta EE)注解
(一)@WebServlet
- 作用
- 用于定义一个Servlet类的配置信息,如URL模式、初始化参数等。在Servlet 3.0及以上版本中,可以通过
@WebServlet
注解来替代web.xml
配置文件。 - 例如,我们可以使用
@WebServlet
注解来定义一个Servlet的URL模式。 -
@WebServlet("/exampleServlet") public class ExampleServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("Hello from Servlet!"); } }
- 用于定义一个Servlet类的配置信息,如URL模式、初始化参数等。在Servlet 3.0及以上版本中,可以通过
- 优势
- 简化了Servlet的配置,避免了繁琐的
web.xml
文件编辑。 - 让Servlet的配置更加直观,直接在代码中定义。
- 简化了Servlet的配置,避免了繁琐的
(二)@WebFilter
- 作用
- 用于定义一个过滤器(Filter)的配置信息,如拦截的URL模式、过滤器的名称等。与
@WebServlet
类似,@WebFilter
注解可以替代web.xml
中的过滤器配置。 - 例如,我们可以定义一个过滤器来拦截所有请求,并打印日志。
-
@WebFilter("/*") public class LoggingFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Request intercepted by LoggingFilter"); chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
- 用于定义一个过滤器(Filter)的配置信息,如拦截的URL模式、过滤器的名称等。与
- 优势
- 简化了过滤器的配置,让过滤器的定义更加清晰。
- 可以直接在代码中指定过滤器的拦截规则,无需额外的配置文件。
(三)@WebListener
- 作用
- 用于标记一个类为监听器(Listener)。监听器可以监听Servlet容器中的事件,如上下文初始化、请求销毁等。
- 例如,我们可以定义一个监听器来监听上下文初始化事件。
-
@WebListener public class ContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("Context initialized"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("Context destroyed"); } }
- 优势
- 简化了监听器的注册过程,无需在
web.xml
中手动配置。 - 让监听器的定义更加直观,直接通过注解标记。
- 简化了监听器的注册过程,无需在
四、Spring框架注解
(一)@Component
- 作用
- 用于标记一个类为Spring的组件,Spring容器会自动检测并实例化这个类。
@Component
是一个通用的注解,通常用于标记普通的组件类。 - 例如,我们可以定义一个普通的组件类。
-
@Component public class ExampleComponent { public void doSomething() { System.out.println("Doing something in ExampleComponent"); } }
- 用于标记一个类为Spring的组件,Spring容器会自动检测并实例化这个类。
- 优势
- 让Spring容器自动管理类的生命周期,无需手动注册Bean。
- 提高了代码的可维护性,让组件的定义更加清晰。
(二)@Service
- 作用
- 用于标记一个类为服务层组件。与
@Component
类似,@Service
也是用于标记Spring管理的Bean,但它更倾向于服务层的逻辑。 - 例如,我们可以定义一个服务类来处理业务逻辑。
-
@Service public class ExampleService { public String process() { return "Processed by ExampleService"; } }
- 用于标记一个类为服务层组件。与
- 优势
- 明确了类的用途,让其他开发者更容易理解代码的结构。
- Spring会自动扫描并注册服务类,简化了配置。
(三)@Repository
- 作用
- 用于标记一个类为持久层组件,通常用于与数据库交互的类。
@Repository
注解可以让Spring容器捕获异常并进行处理,例如将SQLException转换为Spring的DataAccessException。 - 例如,我们可以定义一个数据访问对象(DAO)。
-
@Repository public class ExampleRepository { public void save() { System.out.println("Saving data to database"); } }
- 用于标记一个类为持久层组件,通常用于与数据库交互的类。
- 优势
- 提供了异常处理的便利,让持久层的异常处理更加统一。
- 明确了类的职责,让代码结构更加清晰。
(四)@Controller
- 作用
- 用于标记一个类为Spring MVC的控制器。控制器类负责处理HTTP请求,并返回响应。
- 例如,我们可以定义一个控制器来处理Web请求。
-
@Controller public class ExampleController { @RequestMapping("/example") public String handleRequest() { return "exampleView"; } }
- 优势
- 让Spring MVC框架自动扫描并注册控制器,简化了配置。
- 明确了类的职责,让Web层的代码更加清晰。
(五)@RestController
- 作用
- 用于标记一个类为Spring MVC的RESTful控制器。它结合了
@Controller
和@ResponseBody
的功能,直接返回JSON或XML格式的数据,而不是视图名称。 - 例如,我们可以定义一个RESTful控制器来处理API请求。
-
@RestController public class ExampleRestController { @RequestMapping("/api/example") public String handleApiRequest() { return "Hello from REST API"; } }
- 用于标记一个类为Spring MVC的RESTful控制器。它结合了
- 优势
- 简化了RESTful API的开发,直接返回数据而无需额外的配置。
- 让控制器的职责更加明确,专注于处理API请求。
(六)@RequestMapping
- 作用
- 用于映射HTTP请求到控制器的方法上。它可以指定请求的URL路径、HTTP方法(如GET、POST等)以及其他请求参数。
- 例如,我们可以使用
@RequestMapping
注解来定义一个方法处理GET请求。 -
@Controller public class ExampleController { @RequestMapping(value = "/example", method = RequestMethod.GET) public String handleGetRequest() { return "exampleView"; } }
- 优势
- 提供了灵活的请求映射方式,可以精确地指定请求的处理规则。
- 让控制器的方法与请求的映射关系更加清晰。
(七)@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
- 作用
- 这些注解是
@RequestMapping
的简化版本,分别用于处理GET、POST、PUT和DELETE请求。它们可以让代码更加简洁,避免重复指定HTTP方法。 - 例如,我们可以使用
@GetMapping
注解来处理GET请求。 -
@Controller public class ExampleController { @GetMapping("/example") public String handleGetRequest() { return "exampleView"; } }
- 这些注解是
- 优势
- 让代码更加简洁,减少了
@RequestMapping
注解中的冗余信息。 - 提高了代码的可读性,让请求的处理方式更加直观。
- 让代码更加简洁,减少了
(八)@RequestParam
- 作用
- 用于绑定请求参数到方法的参数上。它可以指定请求参数的名称、是否必填等信息。
- 例如,我们可以使用
@RequestParam
注解来获取请求参数。 -
@Controller public class ExampleController { @GetMapping("/example") public String handleRequest(@RequestParam String name) { return "Hello, " + name; } }
- 优势
- 提供了灵活的请求参数绑定方式,可以指定参数的名称、是否必填等。
- 让方法的参数与请求参数的映射关系更加清晰。
(九)@PathVariable
- 作用
- 用于绑定URL路径中的变量到方法的参数上。它通常用于RESTful API中,通过路径参数来传递数据。
- 例如,我们可以使用
@PathVariable
注解来获取路径中的变量。 -
@RestController public class ExampleRestController { @GetMapping("/example/{id}") public String handleRequest(@PathVariable String id) { return "ID: " + id; } }
- 优势
- 提供了灵活的路径参数绑定方式,让RESTful API的开发更加方便。
- 让方法的参数与路径参数的映射关系更加清晰。
(十)@RequestBody
- 作用
- 用于绑定请求体中的数据到方法的参数上。它通常用于处理POST或PUT请求,将JSON或XML格式的数据自动转换为Java对象。
- 例如,我们可以使用
@RequestBody
注解来接收JSON数据。 -
@RestController public class ExampleRestController { @PostMapping("/example") public String handleRequest(@RequestBody ExampleRequest request) { return "Received: " + request.getName(); } } public class ExampleRequest { private String name; // Getter and Setter }
- 优势
- 提供了自动的数据绑定和类型转换功能,让处理请求体更加方便。
- 让方法的参数与请求体的映射关系更加清晰。
(十一)@ResponseBody
- 作用
- 用于将方法的返回值直接作为响应体返回。它通常用于返回JSON或XML格式的数据,而不是视图名称。
- 例如,我们可以使用
@ResponseBody
注解来返回JSON数据。 -
@Controller public class ExampleController { @RequestMapping("/example") @ResponseBody public String handleRequest() { return "Hello from ResponseBody"; } }
- 优势
- 让方法的返回值直接作为响应体返回,简化了响应的处理。
- 让控制器的方法更加专注于处理数据,而不是视图。
(十二)@Autowired
- 作用
- 用于自动注入Spring容器中的Bean。它可以用于注入依赖,如服务层对象、数据访问层对象等。
- 例如,我们可以使用
@Autowired
注解来注入一个服务类。 -
@Controller public class ExampleController { @Autowired private ExampleService exampleService; @RequestMapping("/example") public String handleRequest() { String result = exampleService.process(); return result; } }
- 优势
- 提供了自动的依赖注入功能,简化了Bean的获取过程。
- 让代码更加简洁,减少了手动获取Bean的代码。
(十三)@Qualifier
- 作用
- 用于指定注入的Bean的名称。当Spring容器中有多个相同类型的Bean时,可以通过
@Qualifier
注解来指定注入哪一个Bean。 - 例如,我们可以定义两个相同类型的Bean,并通过
@Qualifier
注解来指定注入哪一个。 -
@Component public class BeanA { } @Component public class BeanB { } @Controller public class ExampleController { @Autowired @Qualifier("beanA") private BeanA beanA; @Autowired @Qualifier("beanB") private BeanB beanB; }
- 用于指定注入的Bean的名称。当Spring容器中有多个相同类型的Bean时,可以通过
- 优势
- 提供了精确的Bean注入方式,避免了因Bean类型相同而导致的注入错误。
- 让依赖注入更加灵活,可以明确指定注入的Bean。
(十四)@Value
- 作用
- 用于注入配置文件中的值。它可以将配置文件中的属性值注入到字段或方法参数中。
- 例如,我们可以使用
@Value
注解来注入配置文件中的值。 -
@Component public class ExampleComponent { @Value("${example.property}") private String exampleProperty; public void printProperty() { System.out.println("Example Property: " + exampleProperty); } }
- 优势
- 提供了灵活的配置注入方式,让配置文件中的值可以直接注入到代码中。
- 让代码更加简洁,减少了
手动读取配置文件的代码。
(十五)@Configuration
- 作用
- 用于标记一个类为Spring的配置类。配置类可以替代传统的XML配置文件,通过注解的方式来定义Bean和配置。
- 例如,我们可以定义一个配置类来注册Bean。
-
@Configuration public class ExampleConfig { @Bean public ExampleBean exampleBean() { return new ExampleBean(); } }
- 优势
- 提供了注解式的配置方式,让配置更加简洁和直观。
- 让配置类与代码更加紧密地结合在一起,提高了代码的可维护性。
(十六)@Bean
- 作用
- 用于在配置类中定义一个Bean。它通常用于注册自定义的Bean到Spring容器中。
- 例如,我们可以使用
@Bean
注解来定义一个Bean。 -
@Configuration public class ExampleConfig { @Bean public ExampleBean exampleBean() { return new ExampleBean(); } }
- 优势
- 提供了灵活的Bean定义方式,可以在配置类中直接创建和配置Bean。
- 让Bean的定义更加清晰,避免了XML配置文件的复杂性。
(十七)@Profile
- 作用
- 用于指定Bean或配置类在特定的Spring Profile下生效。Spring Profile允许开发者根据不同的环境(如开发环境、测试环境、生产环境)启用不同的Bean。
- 例如,我们可以定义一个Bean,只在开发环境中生效。
-
@Component @Profile("dev") public class DevBean { public void doSomething() { System.out.println("Doing something in Dev environment"); } }
- 优势
- 提供了灵活的环境切换方式,可以根据不同的环境启用不同的Bean。
- 让配置更加灵活,避免了在不同环境中手动切换配置。
(十八)@Transactional
- 作用
- 用于声明事务管理。它可以指定事务的传播行为、隔离级别、超时时间等。
- 例如,我们可以使用
@Transactional
注解来声明一个方法的事务。 -
@Service public class ExampleService { @Transactional public void process() { // Do something } }
- 优势
- 提供了声明式的事务管理方式,让事务的定义更加简洁和直观。
- 让事务的管理更加灵活,可以通过注解来配置事务的各种属性。
(十九)@EnableXXX
注解
- 作用
@EnableXXX
注解用于启用Spring框架的某些特定功能。例如,@EnableWebMvc
用于启用Spring MVC的功能,@EnableTransactionManagement
用于启用事务管理功能。- 例如,我们可以使用
@EnableWebMvc
注解来启用Spring MVC。 -
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { // Custom configurations }
- 优势
- 提供了灵活的功能启用方式,可以通过注解来启用Spring框架的各种功能。
- 让配置更加简洁,避免了繁琐的XML配置文件。
五、JUnit测试框架注解
(一)@Test
- 作用
- 用于标记一个方法为测试方法。JUnit框架会自动运行被标记为
@Test
的方法。 - 例如,我们可以定义一个测试方法来验证某个功能。
-
import org.junit.jupiter.api.Test; public class ExampleTest { @Test public void exampleTest() { // Test logic } }
- 用于标记一个方法为测试方法。JUnit框架会自动运行被标记为
- 优势
- 提供了清晰的测试方法标记方式,让JUnit框架能够自动识别和运行测试方法。
- 让测试代码更加简洁,避免了繁琐的测试方法定义。
(二)@BeforeEach
和@AfterEach
- 作用
@BeforeEach
用于标记一个方法,在每个测试方法执行之前运行。@AfterEach
用于标记一个方法,在每个测试方法执行之后运行。它们通常用于初始化和清理测试环境。- 例如,我们可以定义一个
@BeforeEach
方法来初始化测试数据。 -
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; public class ExampleTest { @BeforeEach public void setUp() { // Initialize test data } @AfterEach public void tearDown() { // Clean up test data } @Test public void exampleTest() { // Test logic } }
- 优势
- 提供了灵活的测试环境初始化和清理方式,让每个测试方法都能运行在相同的环境中。
- 让测试代码更加清晰,避免了重复的初始化和清理代码。
(三)@BeforeAll
和@AfterAll
- 作用
@BeforeAll
用于标记一个方法,在所有测试方法执行之前运行一次。@AfterAll
用于标记一个方法,在所有测试方法执行之后运行一次。它们通常用于初始化和清理整个测试类的环境。- 例如,我们可以定义一个
@BeforeAll
方法来初始化测试类的环境。 -
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; public class ExampleTest { @BeforeAll public static void setUpAll() { // Initialize test class environment } @AfterAll public static void tearDownAll() { // Clean up test class environment } @Test public void exampleTest() { // Test logic } }
- 优势
- 提供了灵活的测试类环境初始化和清理方式,让整个测试类的环境初始化和清理更加高效。
- 让测试代码更加清晰,避免了重复的初始化和清理代码。
(四)@DisplayName
- 作用
- 用于为测试类或测试方法指定一个显示名称。在测试报告中,显示名称会替代默认的类名或方法名。
- 例如,我们可以为测试类和测试方法指定显示名称。
-
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @DisplayName("Example Test Class") public class ExampleTest { @Test @DisplayName("Example Test Method") public void exampleTest() { // Test logic } }
- 优势
- 提供了灵活的测试名称定义方式,让测试报告更加清晰和易读。
- 让测试代码更加友好,方便其他开发者理解测试的意图。
(五)@Tag
- 作用
- 用于为测试类或测试方法添加标签。标签可以用于分类测试,例如根据功能模块或测试类型进行分类。
- 例如,我们可以为测试方法添加标签。
-
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; public class ExampleTest { @Test @Tag("unit") public void exampleTest() { // Test logic } }
- 优势
- 提供了灵活的测试分类方式,可以根据标签选择运行特定的测试。
- 让测试代码更加清晰,方便管理和维护测试。
(六)@Disabled
- 作用
- 用于标记一个测试类或测试方法为禁用状态。被标记为
@Disabled
的测试不会被执行。 - 例如,我们可以禁用一个测试方法。
-
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class ExampleTest { @Test @Disabled public void exampleTest() { // Test logic } }
- 用于标记一个测试类或测试方法为禁用状态。被标记为
- 优势
- 提供了灵活的测试禁用方式,可以在需要时跳过某些测试。
- 让测试代码更加灵活,避免了不必要的测试执行。
(七)@ParameterizedTest
- 作用
- 用于标记一个参数化测试方法。参数化测试允许同一个测试方法运行多次,每次使用不同的参数。
- 例如,我们可以定义一个参数化测试方法。
-
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; public class ExampleTest { @ParameterizedTest @ValueSource(strings = {"test1", "test2"}) public void exampleTest(String input) { // Test logic } }
- 优势
- 提供了灵活的参数化测试方式,可以使用不同的参数运行同一个测试方法。
- 让测试代码更加高效,避免了重复编写测试代码。
(八)@ExtendWith
- 作用
- 用于
扩展JUnit的功能。它可以指定一个扩展类,扩展类可以提供额外的测试功能,例如自定义的测试生命周期、异常处理等。 - 例如,我们可以使用
@ExtendWith
注解来扩展JUnit的功能。 -
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; public class ExampleTest { @Test @ExtendWith(CustomExtension.class) public void exampleTest() { // Test logic } }
- 用于
- 优势
- 提供了灵活的JUnit扩展方式,可以根据需要自定义测试功能。
- 让测试代码更加灵活,可以根据项目需求扩展JUnit的功能。
六、Lombok库注解
Lombok是一个流行的Java库,它通过注解的方式简化了Java代码的编写,尤其是减少了样板代码的生成。
(一)@Data
- 作用
- 用于生成类的getter、setter、
toString
、equals
和hashCode
方法。@Data
注解可以大大减少样板代码的编写。 - 例如,我们可以使用
@Data
注解来生成一个类的所有常用方法。 -
import lombok.Data; @Data public class ExampleClass { private String name; private int age; }
- 用于生成类的getter、setter、
- 优势
- 提供了简洁的代码生成方式,减少了手动编写getter和setter的繁琐。
- 让类的定义更加清晰,避免了冗长的代码。
(二)@Getter
和@Setter
- 作用
@Getter
用于生成类的getter方法,@Setter
用于生成类的setter方法。它们可以分别用于生成单个字段的getter或setter方法。- 例如,我们可以为某个字段生成getter和setter方法。
-
import lombok.Getter; import lombok.Setter; public class ExampleClass { @Getter @Setter private String name; }
- 优势
- 提供了灵活的getter和setter生成方式,可以根据需要为特定字段生成方法。
- 让代码更加简洁,避免了不必要的方法定义。
(三)@ToString
- 作用
- 用于生成类的
toString
方法。@ToString
注解可以根据类的字段自动生成toString
方法的实现。 - 例如,我们可以使用
@ToString
注解来生成toString
方法。 -
import lombok.ToString; @ToString public class ExampleClass { private String name; private int age; }
- 用于生成类的
- 优势
- 提供了简洁的
toString
方法生成方式,减少了手动编写toString
的繁琐。 - 让类的定义更加清晰,避免了冗长的代码。
- 提供了简洁的
(四)@EqualsAndHashCode
- 作用
- 用于生成类的
equals
和hashCode
方法。@EqualsAndHashCode
注解可以根据类的字段自动生成equals
和hashCode
方法的实现。 - 例如,我们可以使用
@EqualsAndHashCode
注解来生成equals
和hashCode
方法。 -
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class ExampleClass { private String name; private int age; }
- 用于生成类的
- 优势
- 提供了简洁的
equals
和hashCode
方法生成方式,减少了手动编写这些方法的繁琐。 - 让类的定义更加清晰,避免了冗长的代码。
- 提供了简洁的
(五)@NoArgsConstructor
、@AllArgsConstructor
和@RequiredArgsConstructor
- 作用
@NoArgsConstructor
用于生成一个无参构造函数,@AllArgsConstructor
用于生成一个包含所有字段的构造函数,@RequiredArgsConstructor
用于生成一个包含所有final
字段的构造函数。- 例如,我们可以使用
@AllArgsConstructor
注解来生成一个全参构造函数。 -
import lombok.AllArgsConstructor; @AllArgsConstructor public class ExampleClass { private String name; private int age; }
- 优势
- 提供了灵活的构造函数生成方式,可以根据需要生成不同类型的构造函数。
- 让代码更加简洁,避免了手动编写构造函数的繁琐。
(六)@Builder
- 作用
- 用于生成一个Builder模式的类。Builder模式可以方便地创建复杂的对象,而不需要编写大量的构造函数。
- 例如,我们可以使用
@Builder
注解来生成一个Builder模式的类。 -
import lombok.Builder; @Builder public class ExampleClass { private String name; private int age; }
- 优势
- 提供了简洁的Builder模式生成方式,让对象的创建更加灵活和方便。
- 让代码更加清晰,避免了复杂的构造函数。
(七)@Slf4j
- 作用
- 用于生成一个日志记录器。
@Slf4j
注解可以自动生成一个日志记录器字段,方便在类中记录日志。 - 例如,我们可以使用
@Slf4j
注解来生成一个日志记录器。 -
import lombok.extern.slf4j.Slf4j; @Slf4j public class ExampleClass { public void doSomething() { log.info("Doing something"); } }
- 用于生成一个日志记录器。
- 优势
- 提供了简洁的日志记录器生成方式,减少了手动定义日志记录器的繁琐。
- 让代码更加清晰,方便记录日志。
七、Hibernate注解
Hibernate是一个流行的Java ORM框架,它通过注解的方式简化了数据库操作。
(一)@Entity
- 作用
- 用于标记一个类为Hibernate的实体类。实体类通常对应数据库中的一个表。
- 例如,我们可以定义一个实体类来对应数据库中的表。
-
import javax.persistence.Entity; import javax.persistence.Id; @Entity public class ExampleEntity { @Id private Long id; private String name; }
- 优势
- 提供了清晰的实体类标记方式,让Hibernate能够自动识别和管理实体类。
- 让代码更加简洁,避免了繁琐的XML配置文件。
(二)@Id
- 作用
- 用于标记实体类中的主键字段。
@Id
注解告诉Hibernate该字段是表的主键。 - 例如,我们可以标记一个字段为主键。
-
import javax.persistence.Entity; import javax.persistence.Id; @Entity public class ExampleEntity { @Id private Long id; private String name; }
- 用于标记实体类中的主键字段。
- 优势
- 提供了清晰的主键标记方式,让Hibernate能够正确处理主键字段。
- 让代码更加简洁,避免了手动定义主键的繁琐。
(三)@GeneratedValue
- 作用
- 用于指定主键的生成策略。
@GeneratedValue
注解可以指定主键的生成方式,例如自增、UUID等。 - 例如,我们可以指定主键的生成策略为自增。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @Entity public class ExampleEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; }
- 用于指定主键的生成策略。
- 优势
- 提供了灵活的主键生成策略,可以根据需要选择不同的生成方式。
- 让代码更加简洁,避免了手动定义主键生成策略的繁琐。
(四)@Column
- 作用
- 用于指定实体类字段对应的数据库列。
@Column
注解可以指定列的名称、是否可空、长度等属性。 - 例如,我们可以为实体类的字段指定列的详细信息。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Column; @Entity public class ExampleEntity { @Id private Long id; @Column(name = "username", nullable = false, length = 50) private String name; }
- 用于指定实体类字段对应的数据库列。
- 优势
- 提供了灵活的字段映射方式,可以精确地控制字段与数据库列的映射关系。
- 让代码更加清晰,避免了字段映射的歧义。
(五)@Table
- 作用
- 用于指定实体类对应的数据库表名。如果没有指定,Hibernate会默认使用类名作为表名。
- 例如,我们可以指定实体类对应的表名。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "example_table") public class ExampleEntity { @Id private Long id; private String name; }
- 优势
- 提供了灵活的表名定义方式,可以根据需要自定义表名。
- 让代码更加清晰,避免了默认表名可能带来的问题。
(六)@Transient
- 作用
- 用于标记实体类中的字段为非持久化字段。被标记为
@Transient
的字段不会被映射到数据库表中。 - 例如,我们可以定义一个非持久化的字段。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Transient; @Entity public class ExampleEntity { @Id private Long id; private String name; @Transient private String transientField; }
- 用于标记实体类中的字段为非持久化字段。被标记为
- 优势
- 提供了灵活的字段定义方式,可以定义一些仅在内存中使用的字段,而不存储到数据库中。
- 让代码更加清晰,避免了不必要的字段映射。
(七)@ManyToOne
、@OneToMany
、@OneToOne
、@ManyToMany
- 作用
- 这些注解用于定义实体类之间的关系。
@ManyToOne
表示多对一关系,@OneToMany
表示一对多关系,@OneToOne
表示一对一关系,@ManyToMany
表示多对多关系。 - 例如,我们可以定义一个一对多关系。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.CascadeType; import java.util.List; @Entity public class ParentEntity { @Id private Long id; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) private List<ChildEntity> children; } @Entity public class ChildEntity { @Id private Long id; @ManyToOne private ParentEntity parent; }
- 这些注解用于定义实体类之间的关系。
- 优势
- 提供了灵活的关系定义方式,可以精确地描述实体类之间的关系。
- 让代码更加清晰,避免了关系映射的歧义。
(八)@JoinColumn
- 作用
- 用于指定外键列的名称。在关系映射中,
@JoinColumn
注解可以指定外键列的详细信息。 - 例如,我们可以指定外键列的名称。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.JoinColumn; @Entity public class ChildEntity { @Id private Long id; @ManyToOne @JoinColumn(name = "parent_id") private ParentEntity parent; }
- 用于指定外键列的名称。在关系映射中,
- 优势
- 提供了灵活的外键定义方式,可以精确地控制外键列的名称和属性。
- 让代码更加清晰,避免了外键映射的歧义。
(九)@Embeddable
和@Embedded
- 作用
@Embeddable
用于标记一个类为可嵌入类,@Embedded
用于将可嵌入类嵌入到实体类中。嵌入类可以将多个字段组合在一起,方便管理。- 例如,我们可以定义一个可嵌入类,并将其嵌入到实体类中。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Embeddable; import javax.persistence.Embedded; @Embeddable public class Address { private String street; private String city; } @Entity public class User { @Id private Long id; @Embedded private Address address; }
- 优势
- 提供了灵活的字段组合方式,可以将多个字段封装在一起,方便管理。
- 让代码更加清晰,避免了字段的冗余定义。
(十)@ElementCollection
- 作用
- 用于映射集合类型字段。
@ElementCollection
注解可以将集合中的元素映射到数据库表中。 - 例如,我们可以定义一个集合字段,并将其映射到数据库表中。
-
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ElementCollection; import java.util.List; @Entity public class User { @Id private Long id; @ElementCollection private List<String> phoneNumbers; }
- 用于映射集合类型字段。
- 优势
- 提供了灵活的集合映射方式,可以将集合中的元素存储到数据库表中。
- 让代码更加清晰,避免了集合字段的复杂映射。
八、其他常用注解
(一)@Log4j2
- 作用
- 用于生成一个Log4j2日志记录器。与
@Slf4j
类似,@Log4j2
注解可以自动生成一个日志记录器字段,方便在类中记录日志。 - 例如,我们可以使用
@Log4j2
注解来生成一个日志记录器。 -
import lombok.extern.log4j.Log4j2; @Log4j2 public class ExampleClass { public void doSomething() { log.info("Doing something"); } }
- 用于生成一个Log4j2日志记录器。与
- 优势
- 提供了简洁的日志记录器生成方式,减少了手动定义日志记录器的繁琐。
- 让代码更加清晰,方便记录日志。
(二)@NonNull
- 作用
- 用于标记字段或方法参数为非空。
@NonNull
注解可以用于静态代码分析工具(如Checker Framework)中,帮助检查空指针异常。 - 例如,我们可以标记一个字段为非空。
-
import org.jetbrains.annotations.NotNull; public class ExampleClass { @NotNull private String name; }
- 用于标记字段或方法参数为非空。
- 优势
- 提供了灵活的非空标记方式,可以帮助静态代码分析工具检查空指针异常。
- 让代码更加清晰,避免了潜在的空指针问题。
(三)@Nullable
- 作用
- 用于标记字段或方法参数为可空。
@Nullable
注解可以用于静态代码分析工具中,帮助检查空指针异常。 - 例如,我们可以标记一个字段为可空。
-
import org.jetbrains.annotations.Nullable; public class ExampleClass { @Nullable private String name; }
- 用于标记字段或方法参数为可空。
- 优势
- 提供了灵活的可空标记方式,可以帮助静态代码分析工具检查空指针异常。
- 让代码更加清晰,避免了潜在的空指针问题。
(四)@CheckReturnValue
- 作用
- 用于标记方法的返回值必须被检查。
@CheckReturnValue
注解可以用于静态代码分析工具中,确保方法的返回值不会被忽略。 - 例如,我们可以标记一个方法的返回值必须被检查。
-
import com.google.errorprone.annotations.CheckReturnValue; public class ExampleClass { @CheckReturnValue public String doSomething() { return "Result"; } }
- 用于标记方法的返回值必须被检查。
- 优势
- 提供了灵活的返回值检查方式,可以帮助静态代码分析工具检查返回值的使用情况。
- 让代码更加清晰,避免了潜在的错误。
(五)@Immutable
- 作用
-
用于标记类为不可变类。
@Immutable
注解可以用于静态代码分析工具中,确保类的实例在创建后不会被修改。 -
例如,我们可以标记一个类为不可变类。
-
import javax.annotation.concurrent.Immutable; @Immutable public class ExampleClass { private final String name; public ExampleClass(String name) { this.name = name; } public String getName() { return name; } }
-
- 优势
- 提供了灵活的不可变类标记方式,可以帮助静态代码分析工具检查类的不可变性。
- 让代码更加清晰,避免了潜在的错误。
(六)@ThreadSafe
- 作用
- 用于标记类为线程安全类。
@ThreadSafe
注解可以用于静态代码分析工具中,确保类的实例在多线程环境下是安全的。 - 例如,我们可以标记一个类为线程安全类。
-
import javax.annotation.concurrent.ThreadSafe; @ThreadSafe public class ExampleClass { private int counter = 0; public synchronized void increment() { counter++; } }
- 用于标记类为线程安全类。
- 优势
- 提供了灵活的线程安全标记方式,可以帮助静态代码分析工具检查类的线程安全性。
- 让代码更加清晰,避免了潜在的线程安全问题。
(七)@GuardedBy
- 作用
- 用于标记字段或方法为线程安全保护。
@GuardedBy
注解可以指定字段或方法被某个锁保护,帮助静态代码分析工具检查线程安全问题。 - 例如,我们可以标记一个字段为线程安全保护。
-
import javax.annotation.concurrent.GuardedBy; public class ExampleClass { private final Object lock = new Object(); @GuardedBy("lock") private int counter = 0; public void increment() { synchronized (lock) { counter++; } } }
- 用于标记字段或方法为线程安全保护。
- 优势
- 提供了灵活的线程安全保护标记方式,可以帮助静态代码分析工具检查线程安全问题。
- 让代码更加清晰,避免了潜在的线程安全问题。
(八)@SuppressWarnings("all")
- 作用
- 用于抑制所有编译器警告。在某些情况下,我们可能需要抑制所有警告,以避免干扰。
- 例如,我们可以使用
@SuppressWarnings("all")
注解来抑制所有警告。 -
@SuppressWarnings("all") public class ExampleClass { public void doSomething() { // Code with potential warnings } }
- 优势
- 提供了灵活的警告抑制方式,可以避免不必要的警告干扰。
- 让代码更加清晰,避免了警告信息的冗余。
(九)@Deprecated(since = "版本号")
- 作用
- 用于标记类、方法或字段为废弃,并指定废弃的版本号。
@Deprecated
注解可以提供更多的上下文信息,帮助开发者了解废弃的版本和原因。 - 例如,我们可以标记一个方法为废弃,并指定废弃的版本号。
-
@Deprecated(since = "1.0", forRemoval = true) public void oldMethod() { System.out.println("This method is deprecated."); }
- 用于标记类、方法或字段为废弃,并指定废弃的版本号。
- 优势
- 提供了灵活的废弃标记方式,可以帮助开发者了解废弃的版本和原因。
- 让代码更加清晰,避免了潜在的错误。
(十)@API
- 作用
- 用于标记类、方法或字段的API级别。
@API
注解可以指定API的稳定性、可见性和其他信息。 - 例如,我们可以标记一个方法为稳定API。
-
import io.github.api4k.API; @API(status = API.Status.STABLE, since = "1.0") public void stableMethod() { System.out.println("This is a stable method."); }
- 用于标记类、方法或字段的API级别。
- 优势
- 提供了灵活的API标记方式,可以帮助开发者了解API的稳定性和版本信息。
- 让代码更加清晰,避免了潜在的错误。