简体   繁体   English

在Java中自动装箱时的NPE

[英]NPE while autoboxing in Java

I have the following piece of code: 我有以下代码:

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
      ...
      ...
   }
}

How is it possible to get an NPE while autoboxing? 自动装箱时如何获得NPE? I can understand getting an NPE on unboxing ie if I had: 我可以理解在拆箱时获得NPE,即如果我有:

long oldVal = map.get(blk)

then that can throw an NPE. 那会抛出NPE。

Edit: Map isn't null. 编辑:地图不为空。 To be more specific, inside the BTreeMap code of mapDB, this line gets executed: 更具体地说,在mapDB的BTreeMap代码内部,执行以下行:

if(key==null) throw new NullPointerException();

In case someone wants to take a look: BtreeMap of mapDB Line: 1024 如果有人想看一下: mapDB的BtreeMap行:1024

Partial stacktrace: 部分堆栈跟踪:

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)

I'm unable to reproduce it so I cannot give a minimal, verifiable example. 我无法复制它,因此无法举一个最小的,可验证的示例。 I have tried to run it so that I perform a get() for a key that doesn't exist, and it DOESN'T give an NPE. 我试图运行它,以便对不存在的键执行get(),并且它不提供NPE。

I think the problem is that you are looking at the wrong version of the BTreeMap code. 我认为问题是您正在查看错误版本的BTreeMap代码。 If you go back to the previous commit of this class , line 1024 is not: 如果返回到该类上一次提交 ,则1024行不是:

if(key==null) throw new NullPointerException();

but: 但:

while(!A.isLeaf()) {...}

where A is set by: 其中A设置为:

BNode A = engine.get(current, nodeSerializer);

This makes much more sense. 这更有意义。 Basically, null is returned from engine.get . 基本上,从engine.get返回null How that is possible is beyond my understanding, but this could very well be a bug of mapdb itself. 这是我无法理解的,但这很可能是mapdb本身的错误。

The NPE could be due to any of the following: NPE可能是由于以下任何原因:

  1. Map being null 地图为空
  2. Passing a null value to get method (not the case) 传递null值以获取方法(情况并非如此)
  3. Passing a key to get() that does not exist in MapDB 将密钥传递给MapDB中不存在的get()

I am more concerned about number 3 in here because, if you pass a key that does not exist then null is returned and trying to store null in Long oldVal cause the exception (I believing that something as follow happens): 我在这里更关心number 3 ,因为,如果传递不存在的键,则返回null,并尝试在Long oldVal存储null导致异常(我相信会发生以下情况):

Long l = new Long(null); //NPE

To find one whether it is #3 do the following 要查找是否是#3,请执行以下操作

//if key don't exist MapDB returns null
if(map.get(blk) != null) { //not null } else { //yes null}

To find out if map is null obviously as pointed out by others, you do as follow 要确定地图是否明显为空(如其他人所指出的那样),请执行以下操作

//invoking get on a null can cause NPE too, so another reason
if(map != null) { // not null } else { //yes null}

To support the fact that #3 could be causing the NPE, see this post with a similiar issue . 要支持#3可能导致NPE的事实,请参阅带有类似问题的帖子。

Looking into the docs for BTreeMap the get(Object) below BTreeMap的文档中查找下面的get(Object)

public V get(Object key)
Specified by:
get in interface Map<K,V>
Overrides:
get in class AbstractMap<K,V>

Looking at Map and AbstractMap the get(Object key) is specified as follow: 查看MapAbstractMap的get(Object key)指定如下:

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. 返回指定键所映射到的值;如果此映射不包含键的映射关系,则返回null。

get(Object) of Map<K,V> and A bstractMap<K,V> returns null if no mapping is found. 如果未找到映射,则Map<K,V>和a bstractMap<K,V> get(Object)返回null It is also capable of throwing NullPointerException . 它还能够抛出NullPointerException So #3 could still be the case that there is no entry for the key passed to get method in map. 因此,#3仍然可能是map中没有为获取方法传递的键条目的情况。

NPE is because map object is null and you are referring to get() method of null,thereby NPE. NPE是因为map对象为null,因此您引用的是null的get()方法,因此是NPE。 Do check of map for null and you will find your solution. 检查地图是否为空,您将找到解决方案。

if(map!=null){
long oldVal = map.get(blk);}
 else {
System.out.println("Map is null");
}

I see only one possibility: The variable "map" is null. 我只看到一种可能性:变量“ map”为空。

Your code sample is incomplete, as you didn't show and where "map" is really initialized. 您的代码示例不完整,因为您没有显示它,并且“ map”实际上是在哪里初始化的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM