前几天上了个小需求,出现了一个空指针的bug
项目中有个抽象基类 abstractBase 里面有很多私有的bean,这个基类有多个实现类ClassA,ClassB等等,其中ClassA中也有跟基类同名的私有属性bean,并且实现了get、set方法,结果导致在基类中用这个bean时报了空指针。
例如:
抽象基类:BaseRepaireService
public abstract class BaseRepaireService implements RepaireService{
private InvoiceService invoiceService;
private String title;
public abstract void print();
public void invoice(){
print();
invoiceService.makeInvoice("维修发票");
}
public InvoiceService getInvoiceService() {
return invoiceService;
}
public void setInvoiceService(InvoiceService invoiceService) {
this.invoiceService = invoiceService;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
具体实现类:OfsRepaireServiceImpl
public class OfsRepaireServiceImpl extends BaseRepaireService {
private InvoiceService invoiceService;
@Override
public void print() {
invoiceService.makeInvoice("外单维修");
}
@Override
public void makeRepaireInvoice(){
super.invoice();
}
@Override
public InvoiceService getInvoiceService() {
return invoiceService;
}
@Override
public void setInvoiceService(InvoiceService invoiceService) {
this.invoiceService = invoiceService;
}
}
配置文件:
测试方法:
@Test
public void repaireServiceTest(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
RepaireService ofsRepaireService = (RepaireService) context.getBean("ofsRepaireService");
ofsRepaireService.makeRepaireInvoice();
}
运行测试方法 报错:
java.lang.NullPointerException
at com.xc.service.BaseRepaireService.invoice(BaseRepaireService.java:17)
at com.xc.service.impl.OfsRepaireServiceImpl.makeRepaireInvoice(OfsRepaireServiceImpl.java:19)
at SrpingParentClassTest.repaireServiceTest(SrpingParentClassTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
在执行基类的 invoiceService.makeInvoice("维修发票"); 语句是抛出的空指针
因为子类重写了基类的get set方法,spring在注入属性的时候实际上是将invoiceService注入到了子类的属性上 而非父类的属性上,所以父类执行时会爆出空指针
可以改成子类里面不重写父类的get set方法 直接调用父类的方法执行:
public class OfsRepaireServiceImpl extends BaseRepaireService {
private InvoiceService invoiceService;
@Override
public void print() {
super.getInvoiceService().makeInvoice("外单维修");
}
@Override
public void makeRepaireInvoice(){
super.invoice();
}
// @Override
// public InvoiceService getInvoiceService() {
// return invoiceService;
// }
//
// @Override
// public void setInvoiceService(InvoiceService invoiceService) {
// this.invoiceService = invoiceService;
// }
}
或者不修改子类而是将基类中的属性用@Resource注解:
public abstract class BaseRepaireService implements RepaireService{
@Resource
private InvoiceService invoiceService;
private String title;
public abstract void print();
public void invoice(){
print();
invoiceService.makeInvoice("维修发票");
}
public InvoiceService getInvoiceService() {
return invoiceService;
}
public void setInvoiceService(InvoiceService invoiceService) {
this.invoiceService = invoiceService;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}