Java 一个合适的模式,而不是返回空值

Java 一个合适的模式,而不是返回空值,java,design-patterns,optimization,Java,Design Patterns,Optimization,在这里使用什么样的模式比较好 我不想返回空值,这感觉不对 另一件事是,如果我想返回导致它为null的原因,该怎么办?若调用者知道它为什么为空,它可以做一些额外的事情,所以我希望调用者知道它并以这种方式行事 Public CustomerDetails getCustomerDetails(){ if(noCustomer){ ..log..etc.. return null; } if(some other bad weird condition)

在这里使用什么样的模式比较好

我不想返回空值,这感觉不对

另一件事是,如果我想返回导致它为null的原因,该怎么办?若调用者知道它为什么为空,它可以做一些额外的事情,所以我希望调用者知道它并以这种方式行事

Public CustomerDetails getCustomerDetails(){
   if(noCustomer){    
     ..log..etc..
     return null;
   }

   if(some other bad weird condition){    
     ..log..etc..
     return null;
   }

   CustomerDetails details= getCustomerDetailsFromSomewhere();

   if (details!=null){
      return details;
   }
   else {
     ..log..etc..
     return null;
   }

}

试试番石榴汁。请参阅这篇关于避免空值的文章:

使用

这会有帮助的

程序员使用null的许多情况都是为了表示某种类型 缺席:可能有价值的地方就有价值 没有,或者找不到一个。例如,Map.get返回null 找不到键的值时

可选是一种用 非空值。可选参数可以包含非空的T引用 (在这种情况下,我们称该引用为“存在”),或者它可能包含 没有(在这种情况下,我们说引用是“不存在的”)。从来都不是 表示“包含空值”

Optional-possible=Optional.of(5);
可能的。isPresent();//返回true
可能的。get();//返回5

我认为您有3个主要选择:

  • 如果null是有效状态,我认为返回null没有问题
  • 如果null是无效状态,则应引发异常
  • 或者利用
如果你在使用谷歌,你也可以使用这个类。

你可以试试

CustomerDetails details = setDetailsToEmpty();
或者其他类似的


您仍然需要检查空或空的客户详细信息。

如果您确实不希望空,请创建一个特殊的CustomerDetails对象

...
        public static final CustomerDetails EMPTY_CUSTOMER_DETAILS = new CustomerDetails();
...    
        public CustomerDetails getCustomerDetails(){
            ...
            if (details!=null){
                return details;
            }
            ...
            return EMPTY_CUSTOMER_DETAILS;

如果您的意思是
null
没有解释它的状态,那么可以使用另一个可以提供更多细节的类包装
CustomerDetails
。例如:

class Feedback()
{
    private CustomerDetails result;
    private int status;

    public static final int STATUS_OK = 0;
    public static final int STATUS_NULL = 1;
    public static final int STATUS_NO_CUSTOMER = 2;
    public static final int STATUS_BAD_CONDITION = 3;

    public Feedback(CustomerDetails result, int status)
    {
        this.result = result;
        this.status= status;
    }

    public CustomerDetails getResult(){return result;}
    public int getStatus(){return status;}
}
并通过以下方式更改您的方法:

Public Feedback getCustomerDetails()
{
   if(noCustomer)
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_NO_CUSTOMER);
   }

   if(some other bad weird condition)
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_BAD_CONDITION);
   }

   CustomerDetails details = getCustomerDetailsFromSomewhere();

   if(details != null)
   {
        return new Feedback(details, Feeback.STATUS_OK);
   }
   else
   {
       ..log..etc..
       return new Feedback(null, Feeback.STATUS_NULL);
   }
}

然后可以通过feedback.getStatus()获取状态,Java中更自然的方法是在错误条件下抛出异常

public CustomerDetails getCustomerDetails(){
   if(noCustomer){    
     ..log..etc..
     throw new NoSuchCustomer(customerName);
   }

   if(some other bad weird condition){    
     ..log..etc..
     throw new IllegalStateException("some other bad weird condition occurred");
   }

   CustomerDetails details= getCustomerDetailsFromSomewhere();

   if (details==null)
      throw new IllegalStateException("Failed to get customer details for "+ customerName);

   return details;
}

方法
getCustomerDetailsFromSomewhere()
可以抛出异常而不是返回null。

为什么您认为返回null不好??有什么具体原因吗?一种可能是,您可以抛出一个
IllegalArgumentException
。或者创建自己的CustomException并使用它。但是,相信我,这比返回null要花更多的时间。现在为什么不想返回null?@gangnamstyleoverflowerr每次调用它时,我都会进行null检查,因为它很容易出错,但主要原因是在这种情况下它“感觉”不对。我可能错了,我认为有一个小错误,你在空检查后返回反馈对象的详细信息,你能通过抛出一个自定义异常来比较这种方法吗?这对我来说似乎更简单me@Spring通过抛出异常,调用方只能以
字符串的形式知道异常的原因。但是对于反馈对象,调用者可以通过
int
知道确切的原因,并以比解析字符串了解原因更好的方式(例如在开关块中)处理它。但是,这两种机制都是正确的,您可以选择一种满足您需要的机制。@Spring如果您每次抛出不同的异常而不是相同的异常,那么调用方可以通过使用多个catch语句来知道确切的原因。实际上,我将在Rest jersey中使用它,根据错误或正确的地方,我想返回正确的http代码并抛出必要的异常,但是我想将这个类与RESTCallsTNX解耦,您能告诉我这种方法的优缺点吗,而不是使用空对象设计模式或使用反馈包装器class@Spring:异常用于表示异常,非预期情况。如果没有客户是正常情况,则返回null或可选值即可。相反,如果没有客户,或者没有这种“糟糕怪异”的情况,那么可能会抛出异常。如果您编写了该方法的合同,并描述了“无客户”和“糟糕的怪异状况”实际上是什么,我们可以给您一个更好的建议。@JB Nizet这些是用户登录的,是用户授权的检查,我需要向调用方类返回一个正确的http代码,因为Jersey rest服务将使用它,并且还有许多其他类似的方法,我想将此服务方法与所有rest相关的类解耦,@JB Nizet在本例中编写一个包装反馈类(如Eng.Fouad sugegsted)它通过返回一个适当的web异常来处理这些情况,我认为这是最好的方法
public CustomerDetails getCustomerDetails(){
   if(noCustomer){    
     ..log..etc..
     throw new NoSuchCustomer(customerName);
   }

   if(some other bad weird condition){    
     ..log..etc..
     throw new IllegalStateException("some other bad weird condition occurred");
   }

   CustomerDetails details= getCustomerDetailsFromSomewhere();

   if (details==null)
      throw new IllegalStateException("Failed to get customer details for "+ customerName);

   return details;
}