找不到导致 NullPointerException 的原因

It'*_*Guy -2 java nullpointerexception

尝试运行我的国际象棋引擎时,我不断收到空指针异常。当我尝试运行我的主要方法时:

package com.chess.engine;

import com.chess.engine.board.Board;

public class JChess {
    public static void main(String[] args) {
        Board board = Board.setupBoard();
        
        System.out.println(board);
    }
Run Code Online (Sandbox Code Playgroud)

}

我从控制台得到这个:

Exception in thread "main" java.lang.NullPointerException
at com.chess.engine.piece.Rook.calculateLegalMoves(Rook.java:45)
at com.chess.engine.board.Board.calculateLegalMoves(Board.java:48)
at com.chess.engine.board.Board.<init>(Board.java:25)
at com.chess.engine.board.Board$Builder.build(Board.java:148)
at com.chess.engine.board.Board.setupBoard(Board.java:123)

at com.chess.engine.JChess.main([JChess.java:7](https://JChess.java:7))
Run Code Online (Sandbox Code Playgroud)

董事会类

package com.chess.engine.board;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.chess.engine.Team;
import com.chess.engine.piece.*;
import com.google.common.collect.ImmutableList;

public class Board {

private final List<Tile> gameBoard;
private final Collection<Piece> whitePieces;
private final Collection<Piece> blackPieces;


private Board(Builder builder) {
    this.gameBoard = createGameBoard(builder);
    this.whitePieces = calculateActivePieces(this.gameBoard,Team.WHITE);
    this.blackPieces = calculateActivePieces(this.gameBoard,Team.BLACK);
    
    final Collection<Move> whiteStdLegalMoves = calculateLegalMoves(this.whitePieces);
    final Collection<Move> blackStdLegalMoves = calculateLegalMoves(this.blackPieces);

}

@Override
public String toString() {
    final StringBuilder builder = new StringBuilder();
    for(int i = 0; i < BoardUtils.NUM_TILES;i++) {
        final String tileText = this.gameBoard.get(i).toString();
        builder.append(String.format("%3s", tileText));
        if((i+1)% BoardUtils.NUM_TILES_PER_NOW == 0) {
            builder.append("\n");
        }
    }
    
    return builder.toString();
    
}
    
private  Collection<Move> calculateLegalMoves(Collection<Piece> pieces) {
    
    final List<Move> legalMoves = new ArrayList<>();
    
    for(final Piece piece: pieces) {
        legalMoves.addAll(piece.calculateLegalMoves(this));
    }
    
    return ImmutableList.copyOf(legalMoves);
}

private static Collection<Piece> calculateActivePieces(final List<Tile> gameBoard, Team team) {

    final List<Piece> activePieces = new ArrayList<>();
    
    for(final Tile tile : gameBoard) {
        if(tile.isTileOccupied()) {
            final Piece piece = tile.getPiece();
            if(piece.getPieceTeam() == team ) {
                activePieces.add(piece);
            }
        }
    }
    return ImmutableList.copyOf(activePieces);
}

public Tile getTile(final int tileCoordinate) {
    return null;
}

private static List<Tile> createGameBoard(final Builder builder){
    final Tile[] tiles = new Tile[BoardUtils.NUM_TILES];
    for(int i = 0; i < BoardUtils.NUM_TILES;i++) {
        tiles[i] = Tile.createTile(i, builder.boardConfig.get(i));
    }
    return ImmutableList.copyOf(tiles);
}
 
public static Board setupBoard() {
    final Builder builder = new Builder();
    
    //Blacks
    builder.setPiece(new Rook(Team.BLACK,0));
    builder.setPiece(new Knight(Team.BLACK,1));
    builder.setPiece(new Bishop(Team.BLACK,2));
    builder.setPiece(new Queen(Team.BLACK,3));
    builder.setPiece(new King(Team.BLACK,4));
    builder.setPiece(new Bishop(Team.BLACK,5));
    builder.setPiece(new Knight(Team.BLACK,6));
    builder.setPiece(new Rook(Team.BLACK,7));
    builder.setPiece(new Pawn(Team.BLACK,8));
    builder.setPiece(new Pawn(Team.BLACK,9));
    builder.setPiece(new Pawn(Team.BLACK,10));
    builder.setPiece(new Pawn(Team.BLACK,11));
    builder.setPiece(new Pawn(Team.BLACK,12));
    builder.setPiece(new Pawn(Team.BLACK,13));
    builder.setPiece(new Pawn(Team.BLACK,14));
    builder.setPiece(new Pawn(Team.BLACK,15));

    // Whites
    builder.setPiece(new Rook(Team.WHITE,48));
    builder.setPiece(new Knight(Team.WHITE,49));
    builder.setPiece(new Bishop(Team.WHITE,50));
    builder.setPiece(new Queen(Team.WHITE,51));
    builder.setPiece(new King(Team.WHITE,52));
    builder.setPiece(new Bishop(Team.WHITE,53));
    builder.setPiece(new Knight(Team.WHITE,54));
    builder.setPiece(new Rook(Team.WHITE,55));
    builder.setPiece(new Pawn(Team.WHITE,56));
    builder.setPiece(new Pawn(Team.WHITE,57));
    builder.setPiece(new Pawn(Team.WHITE,58));
    builder.setPiece(new Pawn(Team.WHITE,59));
    builder.setPiece(new Pawn(Team.WHITE,60));
    builder.setPiece(new Pawn(Team.WHITE,61));
    builder.setPiece(new Pawn(Team.WHITE,62));
    builder.setPiece(new Pawn(Team.WHITE,63));

    builder.setMoveMaker(Team.WHITE);
    
    
    return builder.build();
    
}

public static class Builder {
    
    Map<Integer,Piece> boardConfig;
    Team nextMoveMaker;
    
    public Builder() {
        this.boardConfig = new HashMap<>();
    }
    
    public Builder setPiece(final Piece piece) {
        this.boardConfig.put(piece.getPiecePosition(), piece);
        return this;
    }
    
    public Builder setMoveMaker(Team nextMoveMaker) {
        this.nextMoveMaker = nextMoveMaker;
        return this;
    }
    
    public Board build() {
        
        return new Board(this);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我一直试图弄清楚为什么我已经收到这个错误几个小时了。我检查了电路板构造函数和 Builder 类方法和构造函数,即使在编辑代码后也无法修复错误。

我非常感谢您的帮助并提前致谢。

所有代码都在:https : //github.com/XavierTheCreator/JavaChess

rzw*_*oot 5

这是堆栈跟踪的最顶端:

Exception in thread "main" java.lang.NullPointerException
at com.chess.engine.piece.Rook.calculateLegalMoves(Rook.java:45)
Run Code Online (Sandbox Code Playgroud)

但是您没有包含Rook.java.

我得出的结论是,您真正的问题是:“什么是堆栈跟踪,以及如何阅读它”。因为如果您知道这一点,您肯定不会问这个问题,或者您至少会包含 Rook.java 的第 45 行!

堆栈跟踪将从上到下读取。第一行说明发生了哪个异常(类型),并将包括与之关联的任何消息(此处没有消息)。代码在“堆栈”中工作:当您编写时foo.someMethod(args);,调用 someMethod ,当完成 someMethod 时,控制返回到我们停止的地方。这意味着在每次打印“返回”时代码都会跳回的一系列方法中间有一整堆位置。

这就是你正在见证的。然后,每一行简单地告诉你在哪里。

因此,NPE 发生在 Rook.java 的第 45 行。我们到了 Rook.java 的第 45 行(在calculateLegalMoves方法中),因为第 48 行Board.java调用了那个方法。等等。

如果你已经知道所有这些,嗯,你忘了包括唯一相关的行,而且你确实包括了一整船不相关的代码。