使用 get() from Arrays.asList 时的 NPE - 列表 [重复]

NPE when using get() from Arrays.asList - List [duplicate]

提问人:Artium10 提问时间:1/4/2021 更新时间:1/5/2021 访问量:70

问:

我尝试访问我的 Arrays.asList - List 的一个元素,但我得到了一个 NPE。

主班:

public class Game  {
    List<Cell> cells = null;


    public Game  () {
        cells = new ArrayList<>();
        cells.addAll(Arrays.asList(new Cell[80])); //Target: Add 80 additional list elements
    }

    public int getSelectedValue () {
        return cells.get(10).value;   //Here I get the NPE, but I need the 10th cell
    }

}

子类单元格:

public class Cell {
    int row;
    int col;
    int value;
}

如何实例化具有许多对象(需要 100 个)的 List 并使用 get() 运算符访问这些元素?

java arraylist nullpointerexception

评论

1赞 Hovercraft Full Of Eels 1/4/2021
数组中充满了 null 值
0赞 Artium10 1/4/2021
你的意思是我需要遍历我的完整列表并实例化所有这些列表?有没有快速的方法可以做到这一点?
0赞 Hovercraft Full Of Eels 1/4/2021
狐狸for (Cell cell : cells) { System.out.println(cell); }
1赞 Hovercraft Full Of Eels 1/4/2021
告诉我你看到了什么。请注意,在来到这里之前,您应该进行这种调试
0赞 Artium10 1/4/2021
无法循环访问。我立即收到 NullPointerException: 04:25:49.937 1064-1064/com.example.sudokusolver E/InputEventReceiver: Exception dispatching input event。04:25:49.937 1064-1064/com.example.sudokusolver E/MessageQueue-JNI:MessageQueue 回调中的异常:handleReceiveCallback 04:25:49.944 1064-1064/com.example.sudokusolver E/MessageQueue-JNI:java.lang.NullPointerException:尝试在 om.example.sudokusolver.SudokuGame.getSelectedValue(SudokuG) 的空对象引用上调用虚拟方法“java.lang.String java.lang.Object.toString()”

答:

1赞 Basil Bourque 1/4/2021 #1

为对象的字段请求 null 会引发异常

您建立了一个具有 80 个能够指向对象的插槽的数组。但是你从未创建过任何对象。所以所有八十个插槽都指向什么都没有,它们是.CellCellnull

然后,将该空数组添加到空 .仍然没有对象存在,所以没有对象,只有空值。您确实创建了 80 个插槽,但所有插槽都是空的 (null)。ArrayListCellArrayListCellList

然后,您从列表的第 11 个槽(索引 10)请求要引用的对象。有第十一个插槽。但是在第 11 个插槽中没有对象引用。因此,您从列表中检索到一个 null。

从该 null 中,您尝试访问 中定义的字段。但你手头没有对象。你手里只有一个空。null 表示无意义。尝试访问 null 上的字段(或调用方法)是没有意义的。所以 Java 抛出了一个 .valueCellCellNullPointerException

要验证手头是否有对象引用而不是 null,请执行以下操作:

if( Objects.nonNull( eleventhCell ) ) {…}

使用早期访问 Java 16 定义记录,这是一种创建类的缩写方式。

record Cell ( int row, int col, int val ) {} ;
int initialCapacity = 80 ;
List< Cell > cells = new ArrayList<>( initialCapacity ) ;
for( int i = 1 ; i <= initialCapacity ; i ++ )
{
    cells.add(
        new Cell( 
            ThreadLocalRandom.current().nextInt( 1 , 100 ) ,
            ThreadLocalRandom.current().nextInt( 1 , 100 ) ,
            ThreadLocalRandom.current().nextInt( 1_000 , 10_000 ) 
        )
    );
}
Cell eleventhCell = cells.get( 10 ) ;
if( Objects.nonNull( eleventhCell ) )  // If in doubt, verify not null.
{ 
    int eleventhVal = eleventhCell.val ; 
}


顺便说一句,是 Java 中字段的糟糕名称。作为程序员,我们一直使用这个术语。讨论“价值的价值”会很混乱。value

评论

0赞 Artium10 1/4/2021
非常感谢您的解释!我现在可以使用它了。
0赞 Srikrishna Sharma 1/4/2021 #2

在对对象调用函数之前,请始终在对象上添加 null 检查,以避免 NPE

例如。

public int getSelectedValue () {
 if(cells !=null && cells.size() >0) 
   { 
    if(cells.get(10) !=null)
       return cells.get(10).value;   
   }
    else return null;
}