我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
当前回答
Null不是“问题”。它是完整建模工具集的一个组成部分。软件旨在模拟世界的复杂性,零承担其负担。Null表示Java等中的“无数据”或“未知”。因此,为这些目的使用null是合适的。我不喜欢“空对象”模式;我想谁来守护监护人的问题。如果你问我女朋友的名字,我会告诉你我没有女朋友。在Java语言中,我将返回null。另一种方法是抛出有意义的异常,以指示一些无法(或不希望)立即解决的问题,并将其委派到堆栈中较高的位置,以重试或向用户报告数据访问错误。
对于“未知问题”,给出“未知答案”。(如果从业务角度来看,这是正确的,请确保null安全)在使用前检查方法内的null参数一次,可以避免多个调用方在调用前检查它们。公共照片getPhotoOfThePerson(个人){if(person==null)返回null;//占用一些资源或密集计算//无论如何使用person对象。}前一条导致了正常的逻辑流程,无法从我的照片库中获取不存在的女友的照片。获取人物照片(me.getGirlfriend())它与即将推出的新Java API相匹配(展望未来)getPhotoByName(me.getGirlfriend()?。getName())虽然找不到存储在数据库中的照片是相当“正常的业务流程”,但我过去在一些其他情况下会使用下面这样的配对公共静态MyEnum parseMyEnum(字符串值);//抛出IllegalArgumentException公共静态MyEnum parseMyEnumOrNull(字符串值);不要讨厌键入<alt>+<shift>+<j>(在Eclipse中生成javadoc)并为公共API编写三个额外的单词。除了那些不阅读文档的人,这对所有人来说都绰绰有余。/***@return photo或null*/或/***@return photo,从不为空*/这是一种理论上的情况,在大多数情况下,您应该更喜欢java空安全API(以防它在10年后发布),但NullPointerException是Exception的子类。因此,它是Throwable的一种形式,表示合理的应用程序可能想要捕获的条件(javadoc)!要使用异常的第一个最大优点,并将错误处理代码与“常规”代码分开(根据Java的创建者),对我来说,捕捉NullPointerException是合适的。公共照片getGirlfriendPhoto(){尝试{return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().get-Name());}catch(NullPointerException e){返回null;}}可能会出现以下问题:问:如果getPhotoDataSource()返回null怎么办?答:这取决于业务逻辑。如果我找不到相册,我就不给你看照片。如果appContext未初始化怎么办?该方法的业务逻辑可以满足这一点。如果相同的逻辑应该更严格,那么抛出异常是业务逻辑的一部分,应该使用显式检查null(情况3)。新的Java Null安全API在这里更适合于有选择地指定哪些内容意味着,哪些内容不意味着在发生程序员错误时被初始化为快速失败。Q.可以执行冗余代码,并且可以获取不必要的资源。答:如果getPhotoByName()尝试打开一个数据库连接,创建PreparedStatement,最后将人名用作SQL参数,则可能会发生这种情况。未知问题的方法给出了未知答案(案例1)。在获取资源之前,该方法应检查参数,并在需要时返回“未知”结果。问:由于尝试关闭,这种方法会导致性能损失。A.软件应易于理解和修改。只有在这之后,人们才能考虑性能,而且只有在需要的时候!以及需要的地方!(来源)和许多其他)。PS.这种方法将是合理的,因为单独的错误处理代码和“常规”代码原则在某些地方是合理的。考虑下一个示例:public SomeValue calculateSomeValueUsingSophisticatedLogic(谓词谓词){尝试{Result1 Result1=performSomeCalculation(谓词);Result2 Result2=performSomeOtherCalculation(result1.getSomeProperty());Result3 Result3=performThirdCalculation(result2.getSomeProperty());Result4 Result4=performLastCalculation(result3.getSomeProperty());return result4.getSomeProperty();}catch(NullPointerException e){返回null;}}public SomeValue calculateSomeValueUsingSophisticatedLogic(谓词谓词){SomeValue结果=空;if(谓词!=null){Result1 Result1=performSomeCalculation(谓词);如果(result1!=null&&result1.getSomeProperty()!=空){Result2 Result2=performSomeOtherCalculation(result1.getSomeProperty());如果(result2!=null&&result2.getSomeProperty()!=空){Result3 Result3=performThirdCalculation(result2.getSomeProperty());如果(result3!=null&&result3.getSomeProperty()!=空){Result4 Result4=performLastCalculation(result3.getSomeProperty());if(result4!=null){result=result4.getSomeProperty();}}}}}返回结果;}PPS。对于那些快速向下投票(而且阅读文档的速度不太快)的人,我想说,我一生中从未遇到过空指针异常(NPE)。但这种可能性是Java创建者故意设计的,因为NPE是Exception的子类。我们在Java历史上有过这样一个先例:ThreadDeath是一个错误,不是因为它实际上是一个应用程序错误,而是因为它不打算被捕获!NPE比ThreadDeath更适合作为错误!但事实并非如此。仅当业务逻辑暗示时,才检查“无数据”。public void updatePersonPhoneNumber(长personId,字符串phoneNumber){如果(personId==空)回来DataSource DataSource=appContext.getStuffDataSource();个人=dataSource.getPersonById(personId);if(person!=null){person.setPhoneNumber(电话号码);dataSource.updatePerson(人);}其他{人员=新人员(personId);person.setPhoneNumber(电话号码);dataSource.insertPerson(个人);}}和public void updatePersonPhoneNumber(长personId,字符串phoneNumber){如果(personId==空)回来DataSource DataSource=appContext.getStuffDataSource();个人=dataSource.g
其他回答
您可以考虑空对象是bug的情况,而不是空对象模式(有其用途)。
当抛出异常时,检查堆栈跟踪并解决错误。
如果您使用的是java8或更高版本,请从java.util.Objects获取isNull(yourObject)。
示例:-
String myObject = null;
Objects.isNull(myObject); //will return true
用法:以下代码返回非空值(如果名称不为空,则返回该值,否则返回默认值)。
final String name = "Jobin";
String nonNullValue = Optional.ofNullable(name).orElse("DefaultName");
对于实用程序类,可以检查参数是否为空。
在所有其他情况下,您可能不必这样做。尽可能使用封装,从而减少您想检查null的地方。
这是大多数开发人员最常见的错误。
我们有很多方法来处理这个问题。
方法1:
org.apache.commons.lang.Validate //using apache framework
notNull(对象对象,字符串消息)
方法2:
if(someObject!=null){ // simply checking against null
}
方法3:
@isNull @Nullable // using annotation based validation
方法4:
// by writing static method and calling it across whereever we needed to check the validation
static <T> T isNull(someObject e){
if(e == null){
throw new NullPointerException();
}
return e;
}
我更喜欢这个
public void simpleFunc(SomeObject someObject){
someObject = someObject != null ? someObject : new SomeObject(null);
someObject.doSomething();
}
当然,在我的示例中,SomeObject优雅地处理空参数。例如,记录这样的事件,不做任何其他操作。