Domanda

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.

È stato utile?

Soluzione

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);
    }
}

Altri suggerimenti

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

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.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top