子类与父类同名私有字段时父类字段未Autowired注入,求解决方案
解决方案
方案1:在子类setter中调用父类setter
这是最简洁的修复方式。子类重写setService方法时,先调用父类的setService完成父类私有service字段的初始化,再赋值子类自己的字段:
public class MyClass extends ClassFromLib { private Service service; @Override public void secondaryActivity() { // 自定义逻辑 service.doSomething(); // 自定义逻辑 } @Required public void setService(Service service) { super.setService(service); // 初始化父类的service实例 this.service = service; // 初始化子类的service实例 } }
Spring调用子类的setter时,会同时完成父类和子类service的赋值,既解决了父类mainActivity的NPE问题,也保证子类方法能正常使用service。
方案2:移除子类service字段,复用父类实例(反射兜底)
如果子类仅需调用service.doSomething(),可以不定义自己的service字段。由于父类的service是私有,若父类未提供访问方法,可通过反射获取父类字段(不推荐,仅作兜底):
public class MyClass extends ClassFromLib { @Override public void secondaryActivity() { // 自定义逻辑 try { Field serviceField = ClassFromLib.class.getDeclaredField("service"); serviceField.setAccessible(true); Service service = (Service) serviceField.get(this); service.doSomething(); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException("Failed to access parent service field", e); } // 自定义逻辑 } // 不重写setService,Spring会直接调用父类的setService初始化父类service }
注意:反射会破坏封装,若父类后续修改字段名,代码会失效,仅在无其他方案时使用。
方案3:使用Spring注解自动注入(需开启注解支持)
若项目支持Spring注解,可移除子类的setter,改用@Autowired注入service,同时让Spring调用父类的setter初始化父类字段:
public class MyClass extends ClassFromLib { @Autowired private Service service; @Override public void secondaryActivity() { // 自定义逻辑 service.doSomething(); // 自定义逻辑 } // 不重写setService,Spring自动调用父类的setService }
XML配置可简化(需先开启<context:annotation-config/>或<context:component-scan/>):
<bean id="myClassBean" class="MyClass"/>
父类和子类的service会指向同一个实例,既解决NPE,也保证子类方法正常工作。
内容的提问来源于stack exchange,提问作者SummertimeSadness
相关产品推荐
相关产品推荐

