🤳背景
Guava Cache构建的时候,实现抽象方法的时候,idea默认会提示
Not annotated parameter overrides @ParametersAreNonnullByDefault
parameter Inspection info: Reports problems related to nullability
annotations: overriding problems (for example, when a nullable
parameter is annotated as not-null in the overriding method),
non-annotated getters of annotated fields, and so on.
private final LoadingCache<String, Configure> COMPANY_CODE_CACHE = CacheBuilder.newBuilder()
.initialCapacity(150)
.expireAfterWrite(6, TimeUnit.MINUTES)
.refreshAfterWrite(4, TimeUnit.MINUTES)
.concurrencyLevel(5)
.build(new CacheLoader<String, Configure>() {
@Override
public Configure load(String companyCode) throws Exception {
return configureMapper.selectByCompanyCode(companyCode);
}
});
但是实际上这个方法传递进来的key一定是非空的,但是校验的逻辑是在其他地方,所以idea无法识别。
具体的校验逻辑是在get的时候校验的
com.google.common.cache.LocalCache#get(K, com.google.common.cache.CacheLoader<? super K,V>)
,如下图,在hash之前会先校验key是否为空,null会抛出NullPointerException
🎉问题原因
百度翻译:
Not annotated parameter overrides @ParametersAreNonnullByDefault helps you define that all method parameters in a class or a package have @NotNull semantic, unless they are explicitly annotated with the @Nullable annotation.
未注释的参数重写@ParametersRenonNullByDefault帮助您定义类或包中的所有方法参数都具有@NotNull语义,除非它们使用@Nullable注释显式注释。
@ParametersAreNonnullByDefault
注解是jsr305支持的Java注解,在javax.annotation
包下,我们默认安装的jdk是没有这个注解的,需要单独引入,它还有个兄弟注解ParametersAreNullableByDefault
,其实作用和他们的名字是一样的,就是表示参数默认是不能为空的(ParametersAreNonnullByDefault),和默认可以为空的规范(ParametersAreNonnullByDefault)。有这个的修饰的,如果调用方使用了空值,编译器就能直接给出提示,避免一些传空值的错误。
🐱👓问题复现
简单的复现一下现象和问题
构造两个方法,调用提示
@ParametersAreNonnullByDefault
public class HelloService {
public String getParam(String username) {
return username;
}
public void test() {
String param = getParam(null);
}
}
🐱🐉解决办法
解决办法就是使用对应配套的注解标识
@ParametersAreNonnullByDefault 对应标识 @Nonnull
@ParametersAreNullableByDefault 对应标识 @Nullable
就是名称中包含的关键字,当然你也可以ParametersAreNonnullByDefault 的方法标识@Nullable
那么编译器就会允许空值传递,反之亦然。
private final LoadingCache<String, Configure> COMPANY_CODE_CACHE = CacheBuilder.newBuilder()
.initialCapacity(150)
.expireAfterWrite(6, TimeUnit.MINUTES)
.refreshAfterWrite(4, TimeUnit.MINUTES)
.concurrencyLevel(5)
.build(new CacheLoader<String, Configure>() {
@Override
public Configure load(@Nonnull String companyCode) throws Exception {
return configureMapper.selectByCompanyCode(companyCode);
}
});
🐱🚀结论
基本结论就是这个提示只是规范导致的,帮助编写代码的,所以你如果不想忽略这个,并且遵从规范,就写上对应的注解就好了。当然实际上你写@Nullable也不提示,只是表示的含义容易让人误解。
既然idea支持这个规范(代码中有这个注解标识),那么也就代表开发者想让你也支持这个规范,所以还是按照约定来比较好