想知道这是否是由Guice实例化的对象的包私有构造函数的+ ve副作用。
我有一个看起来像
的课程class Foo { //note the access specifier
private Bar1 iCannotBeNull;
private Bar2 iCannotBeNullEither;
@Inject
Foo(Bar1 bar1, Bar2 bar2) {//note the access specifier
this.iCannotBeNull = Objects.requireNonNull(bar1, "null injected");
this.iCannotBeNullEither = Objects.requireNonNull(bar2, "null injected");
}
}
继续https://github.com/google/guice/wiki/UseNullable,看起来我可以在技术上摆脱空检查,因为我通过包私有构造函数(当然还有Guice模块驻留在同一个包中)确保Foo的对象是由只有Guice,Guice永远不会注入null。
@Inject
Foo(Bar1 bar1, Bar2 bar2) {//note the access specifier
this.iCannotBeNull = bar1;
this.iCannotBeNullEither = bar2;
}
我的理解是正确的,还是我忽略了一些非常明显的东西?
答案 0 :(得分:1)
谷歌的敏捷教练MiškoHevery声称这些checkNotNull
断言在this blog中略微抑制了测试。
例如,向null
传递一个不关心测试的依赖项通常很有用:
testSecureHouse() {
Door door = new Door();
Window window = new Window();
House house = new House(door, window,
null, null, null, null);
house.secure();
assertTrue(door.isLocked());
assertTrue(window.isClosed());
}
如果您订阅此视图,checkNotNull
的替代方法是使用@Nullable
,@NonNull
和@ParametersAreNonnullByDefault
注释:
@Inject
Foo(@NonNull Bar1 bar1, @NonNull Bar2 bar2) {
//
}
如果执行此操作,当开发人员尝试将null
传递给Foo
的ctor时,大多数IDE或lint检查都会发出警告。
总的来说,似乎你必须通过传递null
来平衡便利性和开发人员犯错误的风险。由于您已经很好地组织了包并使用访问修饰符来防止意外使用,因此您的特定情况(仅由Guice模块调用的包私有构造函数)的风险似乎非常低。
如果你的Foo
类是公共API的一部分,那么这将是完全不同的,并且该类肯定会受益于断言并且快速失败。
答案 1 :(得分:0)
不,你不应该删除空检查,因为如上所述,检查代表一般,与Guice无关,快速失败机制:
如果找到空引用,
Preconditions.checkNotNull
可用于快速失败,< ...>
另外,Guice有其特定机制来使用适当的注释来处理可空和非可空的依赖项:
Guice默认禁止
null
。它将拒绝注入null
,而不是ProvisionException
。如果您的班级允许null
,则可以使用@Nullable
为字段或参数添加注释。 Guice会识别任何@Nullable
注释,例如edu.umd.cs.findbugs.annotations.Nullable
或javax.annotation.Nullable
。