【AI问答】Java类中,一些变量设置了@NotNull,怎么在调用内部方法时校验变量是否为空
目录
- 一、Java类中,一些变量设置了@NotNull,怎么在调用内部方法时校验变量是否为空
- 1. 使用断言(`assert`)
- 2. 手动校验
- 3. 使用工具类(如 Apache Commons Lang 或 Spring 的 Assert)
- 使用 Apache Commons Lang
- 使用 Spring 的 Assert
- 4. 使用 AOP(面向切面编程)
- 5. 使用 Lombok 的 `@NonNull` 和 `@Builder`(如果使用 Lombok)
- 总结
- 二、详细说明第五种
- 1. Lombok 简介
- 2. 使用 `@NonNull` 和 `@Builder` 实现非空校验
- 2.1 添加 Lombok 依赖
- 2.2 使用 `@NonNull` 和 `@Builder`
- 3. 代码解析
- 3.1 `@NonNull`
- 3.2 `@Builder`
- 4. 运行结果
- 4.1 正常情况
- 4.2 异常情况
- 5. 优点
- 6. 注意事项
- 7. 总结
有问题问AI的时候,有一些回答比较准确和全面,由于没有时间再二次总结和精炼,直接分享记录一下。
一、Java类中,一些变量设置了@NotNull,怎么在调用内部方法时校验变量是否为空
Kimi: 在Java中,@NotNull
是一个注解,通常用于标记变量、参数或返回值不能为空。它本身并不直接提供运行时的校验功能,而是主要用于代码分析工具(如IDE、静态代码分析工具等)来检测潜在的空指针问题。如果你希望在运行时校验变量是否为空,可以通过以下几种方式实现:
1. 使用断言(assert
)
如果项目开启了断言功能(通过 -ea
参数启动JVM),可以在方法内部使用 assert
来校验变量是否为空。
public class Example {@NotNullprivate String name;public Example(@NotNull String name) {this.name = name;}public void doSomething() {assert name != null : "name should not be null";// 其他逻辑}
}
这种方式的优点是简单,但缺点是断言默认是关闭的,需要在运行时显式开启。
2. 手动校验
在方法内部手动校验变量是否为空,并抛出异常。
public class Example {@NotNullprivate String name;public Example(@NotNull String name) {this.name = name;}public void doSomething() {if (name == null) {throw new IllegalArgumentException("name should not be null");}// 其他逻辑}
}
这种方式的优点是明确且可控,但缺点是需要在每个需要校验的地方手动编写校验代码。
3. 使用工具类(如 Apache Commons Lang 或 Spring 的 Assert)
如果项目中使用了 Apache Commons Lang 或 Spring 框架,可以利用它们提供的工具类来简化校验。
使用 Apache Commons Lang
import org.apache.commons.lang3.Validate;public class Example {@NotNullprivate String name;public Example(@NotNull String name) {this.name = name;}public void doSomething() {Validate.notNull(name, "name should not be null");// 其他逻辑}
}
使用 Spring 的 Assert
import org.springframework.util.Assert;public class Example {@NotNullprivate String name;public Example(@NotNull String name) {this.name = name;}public void doSomething() {Assert.notNull(name, "name should not be null");// 其他逻辑}
}
这种方式的优点是代码简洁,且工具类通常会提供更丰富的校验功能。
4. 使用 AOP(面向切面编程)
如果项目中使用了 Spring 框架,可以通过 AOP 来实现自动校验。创建一个切面类,拦截需要校验的方法,并在方法执行前进行校验。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class NotNullAspect {@Before("execution(* com.example..*(..)) && @annotation(org.jetbrains.annotations.NotNull)")public void checkNotNull() {// 在这里可以获取方法参数或对象属性,并进行校验// 如果发现为空,抛出异常}
}
这种方式的优点是可以集中处理校验逻辑,减少重复代码,但缺点是实现相对复杂,且需要对AOP有一定的了解。
5. 使用 Lombok 的 @NonNull
和 @Builder
(如果使用 Lombok)
如果项目中使用了 Lombok,可以结合 @NonNull
和 @Builder
来简化校验。
import lombok.Builder;
import lombok.NonNull;@Builder
public class Example {@NonNullprivate String name;public void doSomething() {// 其他逻辑}
}
Lombok 会在生成的构造器中自动校验 @NonNull
标记的字段是否为空。这种方式的优点是代码简洁,但缺点是依赖于 Lombok 插件。
总结
- 如果项目中已经使用了 Spring 或 Apache Commons Lang,推荐使用它们提供的工具类进行校验。
- 如果项目中使用了 Lombok,可以结合
@NonNull
和@Builder
来简化校验。 - 如果项目中没有使用上述框架或工具,可以手动校验或使用 AOP 来实现集中校验。
二、详细说明第五种
Kimi: 好的,下面详细说明第五种方法——使用 Lombok 的 @NonNull
和 @Builder
来实现变量的非空校验。
1. Lombok 简介
Lombok 是一个 Java 库,通过注解的方式简化 Java 代码的编写。它可以在编译时自动生成一些常见的代码,如构造器、Getter、Setter、toString
等,从而减少样板代码的编写。
2. 使用 @NonNull
和 @Builder
实现非空校验
2.1 添加 Lombok 依赖
首先,确保你的项目中已经添加了 Lombok 的依赖。如果你使用的是 Maven,可以在 pom.xml
文件中添加以下依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope>
</dependency>
如果你使用的是 Gradle,可以在 build.gradle
文件中添加以下依赖:
implementation 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
2.2 使用 @NonNull
和 @Builder
接下来,我们通过一个示例来展示如何使用 @NonNull
和 @Builder
来实现非空校验。
import lombok.Builder;
import lombok.NonNull;public class Example {@NonNullprivate String name;@Builderpublic Example(@NonNull String name) {this.name = name;}public void doSomething() {// 其他逻辑System.out.println("Name: " + name);}public static void main(String[] args) {// 正常创建对象Example example = Example.builder().name("Kimi").build();example.doSomething();// 尝试创建对象时传入 nulltry {Example exampleWithNull = Example.builder().name(null).build();} catch (NullPointerException e) {System.out.println("Caught NullPointerException: " + e.getMessage());}}
}
3. 代码解析
3.1 @NonNull
@NonNull
是 Lombok 提供的一个注解,用于标记字段或方法参数不能为空。- 当 Lombok 生成代码时,会自动在构造器或方法中插入非空校验逻辑。如果传入的值为
null
,会抛出NullPointerException
。
3.2 @Builder
@Builder
是 Lombok 提供的一个注解,用于生成一个构建器(Builder)模式的类。- 构建器模式是一种设计模式,用于创建对象,特别是当对象的构造参数较多时,可以提供更清晰的代码。
- 在上面的代码中,
@Builder
会生成一个静态的builder()
方法,以及一个build()
方法,用于创建Example
类的实例。
4. 运行结果
运行上述代码,输出如下:
Name: Kimi
Caught NullPointerException: name is marked non-null but is null
4.1 正常情况
当调用 Example.builder().name("Kimi").build()
时,name
参数为非空,对象创建成功,doSomething()
方法正常执行。
4.2 异常情况
当调用 Example.builder().name(null).build()
时,name
参数为 null
,Lombok 生成的构造器会自动抛出 NullPointerException
,提示 name
不能为空。
5. 优点
- 代码简洁:使用 Lombok 的
@NonNull
和@Builder
,可以减少大量的样板代码,使代码更加简洁。 - 自动校验:Lombok 会在生成的构造器中自动插入非空校验逻辑,无需手动编写校验代码。
- 易读性高:通过构建器模式创建对象,代码的可读性更高,特别是当对象的构造参数较多时。
6. 注意事项
- IDE 支持:确保你的 IDE 支持 Lombok,并且已经安装了 Lombok 插件。例如,在 IntelliJ IDEA 中,需要安装 Lombok 插件并启用注解处理器。
- 编译器配置:确保你的编译器配置正确,以便 Lombok 能够正常工作。例如,在 Maven 或 Gradle 项目中,需要正确配置 Lombok 的依赖和注解处理器。
- 异常处理:虽然 Lombok 会自动抛出
NullPointerException
,但你可能需要在调用代码中捕获并处理这些异常,以避免程序崩溃。
7. 总结
通过使用 Lombok 的 @NonNull
和 @Builder
,可以非常方便地实现变量的非空校验。这种方式不仅减少了代码量,还提高了代码的可读性和可维护性。如果你的项目中已经使用了 Lombok,这是一种非常推荐的实现方式。