简体   繁体   中英

Null Pointer exception when trying to return HashMap value in java

I'm working on my java project and get a null pointer exception message when trying to return HashMap value.

public class NgramModel
{
    private HashMap<String,Integer> ngram; 

    public NgramModel() 
    {
        HashMap<String,Integer> ngram = new HashMap <String, Integer>();
        ngram.put("aa", 2);
    }

    public HashMap<String,Integer> getValue() {
        return ngram;
    }
}

When my JUnit test gets to the line:

assertEquals(2,(int)test.getValue().get("aa"));

I have got: no exception message. And the test crashes.

You need to understand variable shadowing.

Begin with a simple example, not using a constructor:

static int test = 10;

public static void main(final String[] args) throws IOException {
    int test = 20;
    System.out.println(test);
}

What does this code print?

The answer is 20 . The reason is that the test you declare in the method is actually a different test to the one you declare in the class. You have two variables in different scopes.

You have the same issue here:

public class NgramModel {

    //one `ngram`
    private HashMap<String,Integer> ngram; 

    public NgramModel() {
        //a second `ngram`
        HashMap<String,Integer> ngram = new HashMap <String, Integer>();
        ngram.put("aa", 2);
    }
}

You do not need to redeclare the variable:

public class NgramModel {

    //one `ngram`
    private HashMap<String,Integer> ngram; 

    public NgramModel() {
        //reference the `ngram` from above
        ngram = new HashMap <String, Integer>();
        ngram.put("aa", 2);
    }
}

The field ngram is still null, as you are declaring a new variable (ngram) in the scope of the constructor. Try the following:

public NgramModel() {
  ngram = new HashMap...
}

Use this way-

import java.util.HashMap;

public class NgramModel
{
    private HashMap<String,Integer> ngram; 

    public NgramModel() 
    {
        ngram = new HashMap <String, Integer>();
        ngram.put("aa", 2);
    }

    public HashMap<String,Integer> getValue() {
        return ngram;
    }
}

OR

import java.util.HashMap;

public class NgramModel
{
    private HashMap<String,Integer> ngram = new HashMap <String, Integer>(); 

    public NgramModel() 
    {
        ngram.put("aa", 2);
    }

    public HashMap<String,Integer> getValue() {
        return ngram;
    }
}

Because, inside your constructor you are creating another local variable and defining it and not defining the class level member variable itself.

The instance member of map type will always be null, if not initialized. In this case, you should rephrase your code something, like that

public class NgramModel
{
    private Map<String,Integer> ngram; 

    public NgramModel() {
        ngram = new HashMap <String, Integer>();
        ngram.put("aa", 2);
    }

    public Map<String,Integer> getValue() {
        return ngram;
    }
}

And do not type any members/variables with implementations. You should be typing with interfaces, if it's possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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