请老司机指点一下,为神马这个代码在 JDK1.8 下能运行, JDK11 下就报 NullPointerException 额

2019-11-13 16:57:39 +08:00
 Wuuuu

刚刚在看黑马 Spring P14 这里,然后按照视频中做的这个 Demo,在 JDK1.8 下面可以正常运行,JDK11 下直接就报错

Exception in thread "main" java.lang.NullPointerException
	at com.itheima.service.impl.AccountServiceImpl.saveAccount(AccountServiceImpl.java:20)
	at com.itheima.ui.Client.main(Client.java:16)

Process finished with exit code 1

一直以为 JDK 都是向后兼容的,不知道有木有老司机指点一下这个是什么原因额……

Debug 的时候也只是看到AccountServiceImpl里面通过BeanFactory.getBean("accountDao");创建的 accountDao 值是 Null,但是完全不知道为什么这个没能创建出来,是 null……

运行的就是 ui 下面的 Client 里面的 main 方法,在 IDEA 里直接右键 run 的……

JDK 一开始用的是 adoptopenjdk 最新的 11.0.5+10,报错,一开始怀疑是 JDK 问题,改成了 amazon-corretto-11.0.3.7.1-1-windows-x64. 还是不行,最后用了 amazon-corretto-8.232.09.1-windows-x64 这个 JDK 成功的……

代码也传到 github 上了。

3785 次点击
所在节点    Java
12 条回复
sagaxu
2019-11-13 17:24:15 +08:00
BeanFactory 的 static initializer 还没执行完,就调用 getBean 方法,返回 null 才符合预期吧,Java 8 能执行才是意料之外。
optional
2019-11-13 17:47:17 +08:00
jdk 的向后兼容最近做的不太好,,我见过好几个应用>11 不能用了
lxk11153
2019-11-13 17:55:55 +08:00
我没 debug,我也同 #1 觉得奇怪呢
1. bean.properties 中先 accountService 后 accountDao
2. 执行 Client main 方法
3. 引用到 BeanFactory,执行它的 static init
4. 先 newInstance accountService,accountService 内部 BeanFactory.getBean("accountDao"),但此时 Map<String,Object> beans 里面没有"accountDao"呀,所以返回 null
Wuuuu
2019-11-13 18:03:07 +08:00
@lxk11153 @sagaxu 谢谢两位额,因为我之前一直没在意静态代码块这里的问题……但是还是不确定怎么才能保证 accoutDao 优先于 accountService 被创建实例额。刚刚我用了一个蠢办法,把 配置文件里面的 dao 和 service 颠倒了一下,也不行……囧
x537196
2019-11-13 18:23:07 +08:00
你放代码出来
sagaxu
2019-11-13 18:35:46 +08:00
@Wuuuu 因为你用的是 Properties,它是无序的
sagaxu
2019-11-13 18:45:42 +08:00
Java 8 下面可用,可能是因为 JDK 8 的 Properties 内部实现,恰好满足了你的加载顺序,纯属巧合。

像 Go 比较愤青,干脆保证无序容器的遍历的随机的,让你不能错误依赖某个具体实现
x537196
2019-11-13 18:48:32 +08:00
@Wuuuu 在 BeanFactory 的静态块中,加一下日志,看看 beans 中的对象是什么状态,什么阶段初始化完成
realpg
2019-11-13 19:10:29 +08:00
一直以为 JDK 都是向后兼容的

何来自信……

JDK 6 7 8 内牛满面
tt0411
2019-11-13 19:13:08 +08:00
我觉得 6 楼是对的, 你这个代码能不能跑和 Properties 内部实现有关; BeanFactory 不应该这么实现的, 去看 Spring 源码吧.
tt0411
2019-11-13 19:26:27 +08:00
看了下 JDK 8 的 Properties 是个 HashTable, 数据放在父类内部数据结构中; 而 JDK 11 的 Properties 虽然依旧继承自 HashTable, 但仅仅实际读写在自己的一个 ConcurrentHashMap.
NoKey
2019-11-13 22:31:18 +08:00
标记一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/619205

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX