V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
Wuuuu
V2EX  ›  Java

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

  •  
  •   Wuuuu · Nov 13, 2019 · 4280 views
    This topic created in 2369 days ago, the information mentioned may be changed or developed.

    刚刚在看黑马 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 上了。

    Supplement 1  ·  Nov 13, 2019

    感谢 @sagaxu @lxk11153 @tt0411 三位的回复,因为我不知道 Properties 的结果是无序,导致一开始没有检查到静态代码块那部分创建实例的地方…… 新的知识点Get√

    看了下网络上解决的方案都是创建一个继承Properties的类覆写其中的方法,之后我也会试着写一下,并且尝试读一下Spring源码。

    当然也知道了 原来JDK向后兼容性没有想象的辣么美好……

    sagaxu
        1
    sagaxu  
       Nov 13, 2019 via Android   ❤️ 1
    BeanFactory 的 static initializer 还没执行完,就调用 getBean 方法,返回 null 才符合预期吧,Java 8 能执行才是意料之外。
    optional
        2
    optional  
       Nov 13, 2019
    jdk 的向后兼容最近做的不太好,,我见过好几个应用>11 不能用了
    lxk11153
        3
    lxk11153  
       Nov 13, 2019   ❤️ 1
    我没 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
        4
    Wuuuu  
    OP
       Nov 13, 2019
    @lxk11153 @sagaxu 谢谢两位额,因为我之前一直没在意静态代码块这里的问题……但是还是不确定怎么才能保证 accoutDao 优先于 accountService 被创建实例额。刚刚我用了一个蠢办法,把 配置文件里面的 dao 和 service 颠倒了一下,也不行……囧
    nimonew
        5
    nimonew  
       Nov 13, 2019
    你放代码出来
    sagaxu
        6
    sagaxu  
       Nov 13, 2019 via Android   ❤️ 1
    @Wuuuu 因为你用的是 Properties,它是无序的
    sagaxu
        7
    sagaxu  
       Nov 13, 2019 via Android   ❤️ 1
    Java 8 下面可用,可能是因为 JDK 8 的 Properties 内部实现,恰好满足了你的加载顺序,纯属巧合。

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

    何来自信……

    JDK 6 7 8 内牛满面
    tt0411
        10
    tt0411  
       Nov 13, 2019   ❤️ 1
    我觉得 6 楼是对的, 你这个代码能不能跑和 Properties 内部实现有关; BeanFactory 不应该这么实现的, 去看 Spring 源码吧.
    tt0411
        11
    tt0411  
       Nov 13, 2019   ❤️ 1
    看了下 JDK 8 的 Properties 是个 HashTable, 数据放在父类内部数据结构中; 而 JDK 11 的 Properties 虽然依旧继承自 HashTable, 但仅仅实际读写在自己的一个 ConcurrentHashMap.
    NoKey
        12
    NoKey  
       Nov 13, 2019
    标记一下
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1408 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 17:13 · PVG 01:13 · LAX 10:13 · JFK 13:13
    ♥ Do have faith in what you're doing.