Java 自动装箱时的 NPE
NPE while autoboxing in Java
我有如下一段代码:
map = db_.treeMapCreate(validMapName_)
.keySerializer(Serializer.LONG)
.valueSerializer(Serializer.LONG)
.make(); //mapDB
protected void onTaskCompletion(TaskInfo task)
{
long startBlk = task.blkId;
long count = task.count;
for (int i=0; i < count; ++i)
{
long blk = startBlk + i;
Long oldVal = map.get(blk); //NPE here
...
...
}
}
如何在自动装箱时获得 NPE?我可以理解在拆箱时获得 NPE,即如果我有:
long oldVal = map.get(blk)
然后可以抛出 NPE。
编辑:地图不为空。更具体地说,在 mapDB 的 BTreeMap 代码中,执行了这一行:
if(key==null) throw new NullPointerException();
万一有人想看:BtreeMap of mapDB
行:1024
部分堆栈跟踪:
java.lang.NullPointerException
at org.mapdb.BTreeMap.get(BTreeMap.java:1024)
at org.mapdb.BTreeMap.get(BTreeMap.java:1013)
at com.service.onTaskCompletion(TaskHandler.java:312)
我无法重现它,所以我无法给出一个最小的、可验证的例子。
我已经尝试 运行 它以便我对不存在的密钥执行 get(),并且它不会给出 NPE。
NPE是因为map对象为null,而你指的是null的get()方法,所以NPE。
检查地图是否为 null,您会找到解决方案。
if(map!=null){
long oldVal = map.get(blk);}
else {
System.out.println("Map is null");
}
我只看到一种可能:变量"map"为空。
您的代码示例不完整,因为您没有显示并且 "map" 真正初始化的地方。
NPE 可能是由于以下任一原因造成的:
- 地图为空
- 将空值传递给 get 方法(不是这种情况)
- 将
get()
中不存在的密钥传递给 MapDB
我更关心这里的 number 3
因为,如果你传递一个不存在的键然后返回 null 并试图在 Long oldVal
中存储 null 导致异常(我相信发生以下情况):
Long l = new Long(null); //NPE
要找到一个是否是 #3,请执行以下操作
//if key don't exist MapDB returns null
if(map.get(blk) != null) { //not null } else { //yes null}
要确定 map 是否如其他人所指出的那样明显为 null,您可以按照以下步骤进行操作
//invoking get on a null can cause NPE too, so another reason
if(map != null) { // not null } else { //yes null}
为了支持 #3 可能导致 NPE 的事实,请参阅此 post 和类似的 issue。
查看 BTreeMap 下面
get(Object) 的文档
public V get(Object key)
Specified by:
get in interface Map<K,V>
Overrides:
get in class AbstractMap<K,V>
查看 Map and AbstractMap get(Object key) 指定如下:
Returns the value to which the specified key is mapped, or null if
this map contains no mapping for the key.
get(Object)
of Map<K,V>
and AbstractMap<K,V>
returns null
如果没有找到映射。它还能够抛出 NullPointerException
。所以#3 仍然可能是这样的情况,即在映射中没有传递给 get 方法的键的条目。
我认为问题在于您查看的 BTreeMap 代码版本错误。如果回到previous commit of this class,第1024行不是:
if(key==null) throw new NullPointerException();
但是:
while(!A.isLeaf()) {...}
其中 A
设置为:
BNode A = engine.get(current, nodeSerializer);
这更有意义。基本上,null
是从 engine.get
返回的。这怎么可能超出我的理解,但这很可能是 mapdb 本身的错误。
我有如下一段代码:
map = db_.treeMapCreate(validMapName_)
.keySerializer(Serializer.LONG)
.valueSerializer(Serializer.LONG)
.make(); //mapDB
protected void onTaskCompletion(TaskInfo task)
{
long startBlk = task.blkId;
long count = task.count;
for (int i=0; i < count; ++i)
{
long blk = startBlk + i;
Long oldVal = map.get(blk); //NPE here
...
...
}
}
如何在自动装箱时获得 NPE?我可以理解在拆箱时获得 NPE,即如果我有:
long oldVal = map.get(blk)
然后可以抛出 NPE。
编辑:地图不为空。更具体地说,在 mapDB 的 BTreeMap 代码中,执行了这一行:
if(key==null) throw new NullPointerException();
万一有人想看:BtreeMap of mapDB 行:1024
部分堆栈跟踪:
java.lang.NullPointerException
at org.mapdb.BTreeMap.get(BTreeMap.java:1024)
at org.mapdb.BTreeMap.get(BTreeMap.java:1013)
at com.service.onTaskCompletion(TaskHandler.java:312)
我无法重现它,所以我无法给出一个最小的、可验证的例子。 我已经尝试 运行 它以便我对不存在的密钥执行 get(),并且它不会给出 NPE。
NPE是因为map对象为null,而你指的是null的get()方法,所以NPE。 检查地图是否为 null,您会找到解决方案。
if(map!=null){
long oldVal = map.get(blk);}
else {
System.out.println("Map is null");
}
我只看到一种可能:变量"map"为空。
您的代码示例不完整,因为您没有显示并且 "map" 真正初始化的地方。
NPE 可能是由于以下任一原因造成的:
- 地图为空
- 将空值传递给 get 方法(不是这种情况)
- 将
get()
中不存在的密钥传递给MapDB
我更关心这里的 number 3
因为,如果你传递一个不存在的键然后返回 null 并试图在 Long oldVal
中存储 null 导致异常(我相信发生以下情况):
Long l = new Long(null); //NPE
要找到一个是否是 #3,请执行以下操作
//if key don't exist MapDB returns null
if(map.get(blk) != null) { //not null } else { //yes null}
要确定 map 是否如其他人所指出的那样明显为 null,您可以按照以下步骤进行操作
//invoking get on a null can cause NPE too, so another reason
if(map != null) { // not null } else { //yes null}
为了支持 #3 可能导致 NPE 的事实,请参阅此 post 和类似的 issue。
查看 BTreeMap 下面
get(Object) 的文档public V get(Object key)
Specified by:
get in interface Map<K,V>
Overrides:
get in class AbstractMap<K,V>
查看 Map and AbstractMap get(Object key) 指定如下:
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
get(Object)
of Map<K,V>
and AbstractMap<K,V>
returns null
如果没有找到映射。它还能够抛出 NullPointerException
。所以#3 仍然可能是这样的情况,即在映射中没有传递给 get 方法的键的条目。
我认为问题在于您查看的 BTreeMap 代码版本错误。如果回到previous commit of this class,第1024行不是:
if(key==null) throw new NullPointerException();
但是:
while(!A.isLeaf()) {...}
其中 A
设置为:
BNode A = engine.get(current, nodeSerializer);
这更有意义。基本上,null
是从 engine.get
返回的。这怎么可能超出我的理解,但这很可能是 mapdb 本身的错误。