通过工厂模式获取对象出现NullPointerException

在这里插入图片描述
话不多说,先上代码:
配置文件
bean.properties

accountDao=cn.study.dao.impl.IAccountDaoImpl
accountService=cn.study.service.impl.IAccountServiceImpl

下面是我的java文件
BeanFactory.java 文件

public class BeanFactory {
     //定义成员变量,用于读取加载配置文件
    private static Properties pro;
    private static Map<String,Object> beans = new HashMap<String,Object>();
     //初始化成员变量
    static{
        try {
            //创建Properties对象
            pro = new Properties();
            //获取配置文件的流对象
            InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //加载配置文件
            pro.load(is);
            //读取配置中所有keys
            Enumeration keys = pro.keys();
            //遍历keys,初始化beans
            while(keys.hasMoreElements()){
                String key = (String)keys.nextElement();
                String beanPath = pro.getProperty(key);
                //创建实例对象
                Object bean = Class.forName(beanPath).newInstance();
                //将key 和 value存放到Map集合中。
                beans.put(key,bean);
            }
        } catch (IOException e) {
            throw new ExceptionInInitializerError("初始化失败了");
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过classname 获取组件对象
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName){
        return beans.get(beanName);
    }
}

IAccountDao.java

public interface IAccountDao {
    void saveAccount();
}

IAccountDaoImpl.java

public class IAccountDaoImpl implements IAccountDao {
    @Override
    public void saveAccount() {
        System.out.println("保存成功");
    }
}

IAccountService.java

public interface IAccountService {
    void saveService();
}

IAccountServiceImpl.java

public class IAccountServiceImpl implements IAccountService {
    private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
    @Override
    public void saveService() {
        accountDao.saveAccount();
        System.out.println(accountDao);
    }
}

测试文件:

public class Test {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
            System.out.println(as);
            as.saveService();
        }
    }
}

运行结果:

Exception in thread "main" java.lang.NullPointerException
cn.study.service.impl.IAccountServiceImpl@7852e922
	at cn.study.service.impl.IAccountServiceImpl.saveService(IAccountServiceImpl.java:12)
	at cn.study.client.Client.main(Client.java:11)
[ERROR] Command execution failed.

首先说,如果将配置文件中的顺序改变如下,就不会报错

accountService=cn.study.service.impl.IAccountServiceImpl
accountDao=cn.study.dao.impl.IAccountDaoImpl

这是为什么呢?
DEBUG分析
在BeanFactory中
pro.load(is)后,
在这里插入图片描述
可以发现,与配置文件中的数据已经改变
从pro中先读取到的的是accountService
而经过Class.forName(beanPath).newInstance()获取到的accountService为:
在这里插入图片描述
可以看见accountDao为null
所以会accoutnDao.save调用时会发生空指针异常
在这里插入图片描述
因为创建accountServiceImpl实例时,成员变量account为null;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值