Java 一个合适的模式,而不是返回空值
在这里使用什么样的模式比较好 我不想返回空值,这感觉不对 另一件事是,如果我想返回导致它为null的原因,该怎么办?若调用者知道它为什么为空,它可以做一些额外的事情,所以我希望调用者知道它并以这种方式行事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)
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;
}