我用object != null了很多东西来避免NullPointerException.
有没有一个很好的替代品呢?
例如:
if (someobject != null) {
someobject.doCalc();
}
Run Code Online (Sandbox Code Playgroud)
NullPointerException当不知道对象是否存在时,这避免了a null.
请注意,接受的答案可能已过期,请参阅/sf/answers/167020941/以获取更新的方法.
我希望使我的代码更具可读性,并使用IDE代码检查和/或静态代码分析(FindBugs和Sonar)等工具来避免NullPointerExceptions.许多工具似乎与彼此的@NotNull/ @NonNull/ @Nonnull注释不兼容,并列出我的代码中的所有这些工具都很难阅读.有什么建议是"最好的"吗?这是我发现的等效注释列表:
javax.validation.constraints.NotNull
创建用于运行时验证,而不是静态分析.
文件
edu.umd.cs.findbugs.annotations.NonNull
由Findbugs静态分析使用,因此Sonar(现为Sonarqube)
文档
javax.annotation.Nonnull
这可能也适用于Findbugs,但JSR-305处于非活动状态.(另请参阅:JSR 305的状态是什么?)
来源
org.jetbrains.annotations.NotNull
由IntelliJ IDEA IDE用于静态分析.
文件
lombok.NonNull
用于控制Project Lombok中的代码生成.
占位符注释,因为没有标准.
来源,
文档
android.support.annotation.NonNull
Android中提供的标记注释,由support-annotations包
文档提供
org.eclipse.jdt.annotation.NonNull
Eclipse用于静态代码分析
文档
我在许多网站上阅读过Optional只能用作返回类型,而不能在方法参数中使用.我很难找到合乎逻辑的原因.例如,我有一个逻辑,它有2个可选参数.因此,我认为像这样编写我的方法签名是有意义的(解决方案1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
Run Code Online (Sandbox Code Playgroud)
许多网页指定Optional不应该用作方法参数.考虑到这一点,我可以使用以下方法签名并添加一个清晰的Javadoc注释来指定参数可能为null,希望将来的维护者将读取Javadoc,因此在使用参数之前始终执行空值检查(解决方案2) :
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Run Code Online (Sandbox Code Playgroud)
或者,我可以用四种公共方法替换我的方法以提供更好的界面并使其更明显p1和p2是可选的(解决方案3):
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Run Code Online (Sandbox Code Playgroud)
现在我尝试编写类的代码,为每种方法调用这条逻辑.我首先从另一个返回Optionals的对象中检索两个输入参数然后调用calculateSomething.因此,如果使用解决方案1,则调用代码将如下所示:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
Run Code Online (Sandbox Code Playgroud)
如果使用解决方案2,则调用代码将如下所示:
Optional<String> …Run Code Online (Sandbox Code Playgroud) 现在已经使用Java 8超过6个月左右,我对新的API更改感到非常满意.我仍然不自信的一个领域是什么时候使用Optional.我似乎想要在任何可能的null地方使用它,而且无处可去.
似乎有很多情况我可以使用它,我不知道它是否增加了好处(可读性/无效安全性)或只是导致额外的开销.
所以,我有一些例子,我对社区是否Optional有益的想法感兴趣.
1 - 当方法可以返回时作为公共方法返回类型null:
public Optional<Foo> findFoo(String id);
Run Code Online (Sandbox Code Playgroud)
2 - 当参数可能是null以下时作为方法参数:
public Foo doSomething(String id, Optional<Bar> barOptional);
Run Code Online (Sandbox Code Playgroud)
3 - 作为bean的可选成员:
public class Book {
private List<Pages> pages;
private Optional<Index> index;
}
Run Code Online (Sandbox Code Playgroud)
4 - 在Collections:
一般来说,我不认为:
List<Optional<Foo>>
Run Code Online (Sandbox Code Playgroud)
添加任何东西 - 特别是因为可以使用filter()删除null值等,但是Optional在集合中是否有任何好的用途?
我错过了什么案例?
就像java.util.Optional<T>在Java 8中(有点)等同于Scala的Option[T]类型,是否有相当于Scala的Either[L, R]?
可选用于表示可为空的对象,此类的一些用途包括
对于第一种情况,我是否需要在所有可空的返回方法中返回Optional?
我试图使用Jackson将类值写入JSON,其中包含Optional作为字段:
public class Test {
Optional<String> field = Optional.of("hello, world!");
public Optional<String> getField() {
return field;
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(new Test()));
}
}
Run Code Online (Sandbox Code Playgroud)
执行时,此类生成以下输出:
{"field":{"present":true}}
Run Code Online (Sandbox Code Playgroud)
我理解当前/不存在的字段被包含在内并且可以在读取JSON数据时解决它,但是我无法解决可选的实际内容永远不会写入输出的事实.:(
除了不使用ObjectMapper之外,这里有任何变通方法吗?
我@Autowired在@Configuration类构造函数下使用注释.
@Configuration
public class MyConfiguration {
private MyServiceA myServiceA;
private MyServiceB myServiceB
@Autowired
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
}
Run Code Online (Sandbox Code Playgroud)
作为Spring文档sais,我能够声明是否需要带注释的依赖项.
如果我@Autowired在构造函数下标记注释required=false,我是说要自动装配的两个服务不是必需的(如Spring文档所示):
@Autowired(required = false)
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
Run Code Online (Sandbox Code Playgroud)
从Spring文档:
在多参数方法的情况下,'required'参数适用于所有参数.
如何required单独为每个构造函数参数设置属性?是否有必要@Autowired在每个领域下使用注释?
问候,
我有一个类Address看起来像这样:
@Value
class Address {
@NotNull String userId;
@NotNull String line1;
String line2;
private Address(Builder b) {
// copy everything from builder
}
// override getter for line2 so that it returns Optional<String>
public Optional<String> getLine2() {
return Optional.ofNullable(this.line2);
}
// and a Builder
public static class Builder {
// builder methods
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我被迫写Builder了一个Getter因为,如果我想在使用Lombok时返回一个Optional,我必须声明line2为Optional<String>.这将生成一个接受的构建器方法Optional<String>!
还有其他方法可以使用lombok Optional吗?
我已经阅读了OptionalJava 8中的目的(遗憾的是我不记得在哪里),我很惊讶作者没有提到在类中使用an Optional作为属性.
由于我在课堂上经常使用选项,我想知道这是不是很好.或者我可以更好地使用普通属性,null它们在未设置时返回?
注意:看起来我的问题可能是基于意见的,但我觉得Optional在课堂上使用的感觉真的不是要走的路(看完上面提到的帖子后).但是,我喜欢使用它,并且找不到使用它的任何缺点.
例
我想举一个例子来澄清.我有一个类Transaction,它是这样构建的:
public class Transaction {
private Optional<Customer> = Optional.empty();
....
Run Code Online (Sandbox Code Playgroud)
VS
public class Transaction {
private Customer = null;
....
Run Code Online (Sandbox Code Playgroud)
当在一个检查Customer,我认为这是最合理的使用transaction.getCustomer().isPresent()比transaction.getCustomer() != null.在我看来,第一个代码比第二个代码更清晰.
java ×9
java-8 ×6
optional ×5
null ×2
annotations ×1
autowired ×1
constructor ×1
guava ×1
ide ×1
jackson ×1
lombok ×1
object ×1
scala ×1
spring ×1
spring-boot ×1