Java 在两个变量之间交替写入空检查?
我有点困惑。 我有两个对象Java 在两个变量之间交替写入空检查?,java,Java,我有点困惑。 我有两个对象A和B。 它们可以是null,也可以不是null,我必须在所有这些情况下执行一些不同的业务逻辑 目前我有: if(A != null && B != null) { /* operation1 */ } if(A == null && B == null) { /* operation2 */ } if(A != null && B == null) { /* operation3 */ } if(A == null
A
和B
。
它们可以是null
,也可以不是null
,我必须在所有这些情况下执行一些不同的业务逻辑
目前我有:
if(A != null && B != null) { /* operation1 */ }
if(A == null && B == null) { /* operation2 */ }
if(A != null && B == null) { /* operation3 */ }
if(A == null && B != null) { /* operation4 */ }
你能给我推荐一种更优雅的书写
if
s的方法吗?为了避免多次检查相同的条件:
if (A != null) {
if (B != null) {
// operation1
} else {
// operation3
}
} else {
if (B != null) {
// operation4
} else {
// operation2
}
}
但这并不能真正让代码看起来更优雅。下面是使用嵌套if/else的等效解决方案:
if(A != null)
{
if(B != null)
{
/* operation1 */
}
else
{
/* operation3 */
}
}
else
{
if(B != null)
{
/* operation4 */
}
else
{
/* operation2 */
}
}
正如您可以清楚地看到的,“如果a…b…c…条件成立,则执行xyz”的语义在这种方法中就不那么清晰了。因此,您提出的“不雅”方法实际上是一段逻辑清晰的代码。充其量,您可以执行以下操作:
// Using a helper class with method names that
// clearly communicate intent/meaning in the null checks:
class Logics
{
public static boolean allNull(Object... objs)
{
for(Object o : objs)
if(o != null)
return false;
return true;
}
public static boolean noneNull(Object... objs)
{
for(Object o : objs)
if(o == null)
return false;
return true;
}
}
...
if(Logics.noneNull(A, B)) { /* operation1 */ }
if(Logics.allNull(A, B)) { /* operation2 */ }
if(A != null && B == null) { /* operation3 */ }
if(A == null && B != null) { /* operation4 */ }
你可以做到以下几点,尽管这比你已经拥有的更好还是更差(这还不错)还有争议:
您可以结合以下内容执行类似操作:
谓词isNull=Objects::isNull;//或o->o!=无效的
谓词isNotNull=Objects::nonNull;//或o->o==null
如果(isNull.test(A)){
if(isNotNull.test(B)){
/*操作1*/
}
否则{
/*操作2*/
}
}
否则{
如果(isNull.test(B)){
/*操作3*/
}
否则{
/*操作4*/
}
}
事实上,如果您希望在调用方法中保持if条件可见,那么您的代码是一个比叠置if条件的解决方案更好的选择。所有这些if-else和内部if-else语句都使触发每个操作的条件变得不那么明显。所以你可以保持你的方法。看
您可以做的一个小改进是从if条件中提取方法,并以记录决策的方式命名新方法:
if(是否有ACARANDENOUGHGAS(A,b)){//驱动操作}
if(是否有AcarandNogas(A,b)){//行走操作}
...
私有布尔值是youhaveAcarandenoughgas(…){返回A!=null&&B!=null;}
如果您想要/需要更新奇的东西,可以使用命令模式或策略。根据经验,重复的if-else语句或开关是符号,您可以使用多态性获得相同的结果。看
接口操作{
void execute();
}
类操作生成器{
公共静态操作构建(类型A、类型B){
如果(A!=null&&B!=null){返回新的OperationOne();}
如果(A==null&&B==null){returnnewoperationtwo();}
如果(A!=null&&B==null){/*操作3*/}
如果(A==null&&B!=null){/*操作4*/}
}
类OperationOne实现操作{
私有操作ONE(){…}
@凌驾
void execute(){…}
}
类操作两个实现操作{
私有操作二(){}
@凌驾
void execute(){…}
}
}
用这个你只要
Operation op=OperationBuilder.build(A,B);
op.execute();
下面是为什么这比您开始时的更好。想象一下你有
if(codition1){
//complicated stuff here that makes you scroll and scroll
}
if(codition2){
//complicated stuff here that makes you scroll and scroll
}
etc
您可能无法在同一屏幕上看到所有条件,因此您无法了解正在发生的情况。另一方面,构建器保持所有条件的严密性和干净性,同时再次将操作逻辑与噪声分离。如果需要执行4种不同的操作,除了使用
else If
,或嵌套If(A!=null){If(B!=null){}
,实际上,除了嵌套if-else语句之外,您可以做的事情并不多。嵌套if-else语句实际上是一种代码味道,所以您不应该这么做。开关与您已有的开关是一样的,无论如何,它们不适用于此类比较,而不会使代码复杂化。这种样式使读取条件变得更加困难。问问自己,在什么情况下你会做操作2,例如,你最终会做一些容易出错的心理操作。这是一个不错的黑客行为,但事实上它增加了代码的复杂性:因此理解代码会更加困难,并且会更加努力确保代码不会出错。所以我不会这么做,注意数字00
,01
,10
和11
看起来像二进制数,但实际上是八进制和十进制数。为什么不使用实数二进制数,在它们前面加上0b
<代码>0b00,0b01
,0b10
,0b11
。
Predicate<Object> isNull = Objects::isNull; // or o -> o != null
Predicate<Object> isNotNull = Objects::nonNull; // or o -> o == null
if (isNull.test(A)) {
if (isNotNull.test(B)) {
/* operation1 */
}
else {
/* operation2 */
}
}
else {
if(isNull.test(B)) {
/* operation3 */
}
else {
/* operation4 */
}
}
if(codition1){
//complicated stuff here that makes you scroll and scroll
}
if(codition2){
//complicated stuff here that makes you scroll and scroll
}
etc