• Java Properties的null值


    环境

    • Ubuntu 22.04
    • Java 17.0.3.1

    HashMap和ConcurrentHashMap

    HashMap

            Map map1 = new HashMap();
            map1.put("key1", "value1");
            map1.put("key2", "value2");
            map1.put("key3", "");
            map1.put("key4", null);
    
            System.out.println(map1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果如下:

    {key1=value1, key2=value2, key3=, key4=null}
    
    • 1

    ConcurrentHashMap

            Map map1 = new ConcurrentHashMap();
            map1.put("key1", "value1");
            map1.put("key2", "value2");
            map1.put("key3", "");
            map1.put("key4", null); // 此处抛出异常
    
            System.out.println(map1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    报错如下:

    Exception in thread "main" java.lang.NullPointerException
    	at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    	at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
    	at pck1.Test0824.main(Test0824.java:28)
    
    • 1
    • 2
    • 3
    • 4

    查看 ConcurrentHashMapput() 方法,如下:

        /**
         * Maps the specified key to the specified value in this table.
         * Neither the key nor the value can be null.
         *
         * 

    The value can be retrieved by calling the {@code get} method * with a key that is equal to the original key. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with {@code key}, or * {@code null} if there was no mapping for {@code key} * @throws NullPointerException if the specified key or value is null */ public V put(K key, V value) { return putVal(key, value, false); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    keyvalue 上都有 @NotNull 注解,且注释里也提到了,如果 key 或者 valuenull ,就会抛出 NullPointerException

    再查看 putVal() 方法,如下:

        final V putVal(K key, V value, boolean onlyIfAbsent) {
            if (key == null || value == null) throw new NullPointerException();
        ......
    
    • 1
    • 2
    • 3

    总结

    HashMap 可以插入null值,但是 ConcurrentHashMap 不能插入null值,否则会抛NPE异常。

    Properties

    插入

            Properties p = new Properties();
            p.put("key1", "value1");
            p.put("key2", "value2");
            p.put("key3", "");
    //        p.put("key4", null);
    
            System.out.println(p);
    
            Object obj = p.getProperty("key3");
    
            System.out.println(obj == null ? "null" : "not null");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果如下:

    {key1=value1, key2=value2, key3=}
    not null
    
    • 1
    • 2

    其中, key3 的值是空字符串( "" ),而不是null。

    如果试图插入null值(将上面代码中的 key4 所在行反注释),则报错如下:

    Exception in thread "main" java.lang.NullPointerException
    	at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    	at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
    	at java.base/java.util.Properties.put(Properties.java:1301)
    	at pck1.Test0824.main(Test0824.java:14)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    从调用栈可见, Properties 使用的是 ConcurrentHashMap ,所以,显然无法插入null值。

    读取

    创建文件 test.properties 如下:

    key1=value1
    key2=value2
    key3=
    
    • 1
    • 2
    • 3

    读取 test.properties 文件:

            Properties properties = new Properties();
            InputStream in = Test0824.class.getClassLoader().getResourceAsStream("pck1/test.properties");
            try {
                properties.load(in);
    
                String value1 = properties.getProperty("key1");
                System.out.println(value1);
    
                String value2 = properties.getProperty("key2");
                System.out.println(value2);
    
                String value3 = properties.getProperty("key3");
                System.out.println(value3);
                System.out.println(value3 == null); // false
                System.out.println(value3.equals("")); // true
    
                String value4 = properties.getProperty("key4");
                System.out.println(value4);
                System.out.println(value4 == null); // true
    
            } finally {
                in.close();
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行结果如下:

    value1
    value2
    
    false
    true
    null
    true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可见,对于 key3= 这样的配置,读取的value是空字符串( "" ),而不是null值。而对于不存在的key值(比如本例中的 key4 ),读取的value是null值。

    反过来想,之所以Properties里除非是不存在的key值,否则读取和插入都不存在null值的情况,也许目的正是为了区分key值是否存在吧。

    总结

    只有读取不存在的key值时,才会出现null值,否则无论读取或插入,都不存在value为null值的情况(读取为空字符串,插入报错NPE)。

    具体如下:

    • 对于 key= 这样的配置,读取的value是空字符串( "" );
    • 对于不存在的key值,读取的value是null值;
    • 插入时,不允许value为null值,否则抛出NPE异常;
  • 相关阅读:
    基于微信小程序的心理自测咨询APP设计与实现-计算机毕业设计源码+LW文档
    腾讯云轻量应用服务器怎么样?来自学生的评价
    亚马逊登山扣 安全带的要求标准ASTM1774 ASTM F1772办理
    uniapp 如何使用自定义插槽 slot
    LeetCode --- 1356. Sort Integers by The Number of 1 Bits 解题报告
    odoo 开发入门教程系列-准备一些操作(Action)?
    微服务天花板,Alibaba Cloud Alibaba 精通笔记,知乎牛客狂转 10w 次,github 狂揽 14k 星
    养殖自动化管理系统:开启智慧养殖新篇章
    Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    1044 火星数字 (测试点2.4说明)
  • 原文地址:https://blog.csdn.net/duke_ding2/article/details/126513837