java如何避免传递null-空对象模式

java如何避免传递null-空对象模式

示例代码:


public class CustomerFactory {

  private static final String[] DATA = {"1", "2", "3"};

  public RealDataQuery query(String query) {

    for (String dataId : DATA) {
      if (dataId.equals(query)) {
        return new RealDataQuery();
      }
    }

    return null;
  }
}

public class RealDataQuery {

  public String query() {
    return "success";
  }
}


public class TestCustomerFactory {

  @Test
  public void testCustomer() {
    CustomerFactory factory = new CustomerFactory();

    for (int i = 0; i < 6; i++) {
      RealDataQuery customer = factory.query(String.valueOf(i));
      System.out.println(customer.query());
    }
  }
}

运行,空指针来袭

java.lang.NullPointerException
        at com.TestCustomerFactory.testCustomer(TestCustomerFactory.java:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

空对象模式

关键记住一点:不到万不得已,千万别在产品代码中传递null。
在编写测试时,如果发现某个对象需要的某参数难以构建,便可以考滤传递一个null,这样一来如果这个参数在测试过程中被用到了的话,
代码就会抛出一个异常,而测试用具这会捕获这个异常,这时候,如果确实需要一个对象而非null的话,再去构建这个对象并将它作为参数再传递也不晚。
传null的手法在某些语言中是一项非常便利的技术,在java和C#中使用起来没有什么问题,其实只要是那些会对运行期使用空引用抛出异常的语言,这项技术都适用。

1. 声明公共的接口

/**
 * 查询的接口
 *
 * @version 0.0.1
 */
public interface CustomerInf {

  /**
   * 定义查询方法
   *
   * @return 查询的结果
   */
  String query();

  /**
   * 是否为null
   *
   * @return
   */
  boolean isNul();
}



/**
 * 用来模拟实际的查询操作
 *
 * @version 0.0.1
 */
public class RealDataQuery implements CustomerInf {

  @Override
  public String query() {
    return "success";
  }

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

/**
 *  当为空的时候的处理。
 *
 * @version 0.0.1
 */
public class NullQuery implements CustomerInf {

  @Override
  public String query() {
    return "can not find";
  }

  @Override
  public boolean isNul() {
    return true;
  }
}


/**
 * 对象工厂
 * 返回值做出修改 
 *
 * @author liujun
 * @version 0.0.1
 */
public class CustomerFactory {

  private static final String[] DATA = {"1", "2", "3"};

  public CustomerInf query(String query) {

    for (String dataId : DATA) {
      if (dataId.equals(query)) {
        return new RealDataQuery();
      }
    }

    return new NullQuery();
  }
}

public class TestNullObject {

  @Test
  public void testCustomer() {
    CustomerFactory factory = new CustomerFactory();

    for (int i = 0; i < 6; i++) {
      CustomerInf customer = factory.query(String.valueOf(i));
      System.out.println(customer.query());
    }
  }
}

经过这个操作之后,不会再有空指针异常异常的犯脑了,

没有空指针了,就不一定没有问题了:


public class TestNullObject {

  @Test
  public void testCustomerCount() {
    CustomerFactory factory = new CustomerFactory();

    int countNum = 0;
    for (int i = 0; i < 6; i++) {
      CustomerInf customer = factory.query(String.valueOf(i));
      System.out.println(customer.query());
      countNum++;
    }
    System.out.println(countNum);
  }
}


这段统计就是一个代表。因为中间包含了空对象,所以统计就是错误的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值