Get around java's try/catch and keep the code clean without returning a null

China☆狼群 提交于 2019-12-08 05:30:31

Well, is value not found something exceptional (indicating an error) or probable? If it is absolutely not possible that doSomething() can't find what it needs, this is an error. I guess myFunc() is not the right place to handle such error.

If doSomething() sometimes can't find this or that (because the input is incorrect, misconfiguration, etc.) then it should not throw an exception and let the client handle this expected situation. However null is not the best return value. Instead consider design pattern or some wrapper like Option[T] in Scala.

This is one of the reasons why InputStream is not simply throwing EOFException when it reaches end of file. This is not an unexpected situation.

In Java I try to follow some techniques/naming conventions to make null more obvious:

private Obj tryReturningSomething()
private Obj returnSomethingOrNull()

Also you can always use JavaDoc to document possible return value. I agree returning null is not the best approach (e.g. when method returns a collection, I always return an empty one instead of null) but in your case it is still better than throwing an exception to be caught one stack frame above. This is wasteful, harder to maintain and read. Consider having two version - one returning null and one throwing an exception, wrapping the first one.

Exception handling was invented to handle errors, not to control the program flow.

A database lookup is a case where "no value found" is an expected occurrence. Exceptions are for handling exceptional circumstances that do not happen in normal use.

The cleanest way is to change your database API to return null on no value found. Then you do not have to worry about try/catch blocks at all and just propagate the null.

A nice side bonus is that using exceptions for flow control is relatively slow, so you will see nice performance improvements.

It's 6 of 1 and 1/2 dozen of another. It really depends on what you want to do with the end result and if doSomething() is going to be used outside of this single use-case. The advantage of not throwing an exception is that you can return a known value when the exception occurs.

Either approach is acceptable. The most important thing is that you document the behavior of your function.

If db.getValue() cannot return null, then the second option is probably easier. If it can, however, then you want a way to know whether the value is null or there is none.

Some standard library classes do it both ways, implementing one function that throws an exception and another that returns null.

I am planning to do something like this (documented here):

public class NullUser extends User {  

  public static final NullUser INSTANCE = new NullUser();  

  public static NullUser getInstance() {  
    return INSTANCE;  
  }  

  @Override  
  public boolean isAuthenticated() {  
    return false;  
  }  

  private NullUser() {  
  }  
}  



    public User getUser() {  
      if (/*some condition*/) {  
        return user;  
      } else {  
        return NullUser.getInstance();  
      }  
    }  



if (obj.getUser().isAuthenticated() {  
  // allow  
} 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!