包含私有构造函数的类的正面副作用以及通过Guice实例化的相应对象?

时间:2017-08-16 21:52:30

标签: java guice

想知道这是否是由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;
  }   

我的理解是正确的,还是我忽略了一些非常明显的东西?

2 个答案:

答案 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可用于快速失败,< ...>

     

- UseNullable · google/guice Wiki · GitHub

另外,Guice有其特定机制来使用适当的注释来处理可空和非可空的依赖项:

  

Guice默认禁止null。它将拒绝注入null,而不是ProvisionException。如果您的班级允许null,则可以使用@Nullable为字段或参数添加注释。 Guice会识别任何@Nullable注释,例如edu.umd.cs.findbugs.annotations.Nullablejavax.annotation.Nullable

     

- UseNullable · google/guice Wiki · GitHub