空指针异常 (Java)

NullPointerException (Java)

我已经尝试查看有关此问题的帖子,但我的代码中仍然遇到此错误的问题。所以在第四行,我创建了一个名为 SongDatabase 的实例变量来访问 SongDatabase class。但是当我到达 case 1 下的 SongDatabase.addNewSong(); 行时,我得到一个 java.lang.NullPointerException: null 错误。

接口class:

public class Interface 
{
    Scanner console = new Scanner(System.in);
    private SongDatabase SongDatabase;

    public static void main(String[] args) {
        Interface intFace = new Interface();
        intFace.run();
    }

    private void run() {
        switch (userInput) {
        case 1: 
            SongDatabase.addNewSong();
            break;
        case 2:
            SongDatabase.removeSong();
            break;
        case 3:
            SongDatabase.sortSongs();
            break;
        default:
            System.out.println("Please enter a valid number.");
            break;

    }
}

歌曲数据库class:

public class SongDatabase {
    Scanner console = new Scanner(System.in);  
    private Song song1, song2, song3, song4;

public void addNewSong() {        
        if (song1 == null) {
            song1 = getFromUser();
        }
        else if (song2 == null) {
            song2 = getFromUser();
        }    
        else if (song3 == null) {
            song3 = getFromUser();
        }
        else if (song4 == null) {
            song4 = getFromUser();
        }
        else {
        System.out.println("The database is currently full. Please delete a song before adding a new one.");
       }    
    }

我已经调试了调试器,我知道实例变量 SongDatabase = null,这可能是导致错误的原因?我之前有一行

SongDatabase SongDatabase = new SongDatabase();
SongDatabase.addNewSong();

相反,但我意识到这是每次都创建一个新的 SongDatabase 对象并擦除我存储在其中的内容,因此我不得不更改它。我真的很感激一个解决方案,因为我不知道,谢谢!

它为空,因为它从未被实例化。在您的主要方法中创建 SongDatabase 以解决您原来的问题:

public static void main(String[] args) {
    Interface intFace = new Interface();
    SongDatabase = new SongDatabase();
    SongDatabase.addNewSong();
    intFace.run();
}

您不应将实例字段与 class 同名,因为这会导致 Variable shadowing - Wikipedia says (in part) variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking。你可以在声明中定义引用,比如

private SongDatabase songDatabase = new SongDatabase();

然后像

private void run() {
    switch (userInput) {
    case 1: 
        songDatabase.addNewSong();
        break;
    case 2:
        songDatabase.removeSong();
        break;
    case 3:
        songDatabase.sortSongs();
        break;
    default:
        System.out.println("Please enter a valid number.");
        break;
    }
}

为避免混淆,以小写字母开头的变量命名。

 private SongDatabase songDatabase;

这样很明显,当您写 songDatabase 时,您指的是实例,而当您写 SongDatabase 时,您指的是 class。

您需要实例化 class 的实例才能使用它。看来您已经从问题中意识到了这一点,但这只是在哪里做的问题。为了快速修复,您可以在声明变量的地方实例化它。稍后您可以研究更好的设计。因此:

 private SongDatabase songDatabase = new SongDatabase();

您得到的是 NullPointerException,因为 SongDatabase 的 class 变量从未实例化过。要初始化 class 变量,我们可以使用构造函数,请参阅下面的代码详细信息。同样为了避免命名混乱,我们可以使用 this 关键字来提高代码的可读性。

import java.util.Scanner;

public class Interface
{
    private Scanner console;
    private SongDatabase songDatabase;

    public Interface()
    {
        this.songDatabase = new SongDatabase(); // Initialize the SongDatabase class and .
        this.console = new Scanner(System.in); // Initialize the console reference with scanner class.
    }

    public static void main(String[] args)
    {
        Interface intFace = new Interface();
        intFace.run();
    }

    private void run()
    {
        System.out.println("1. Add Song");
        System.out.println("2. Remove Song");
        System.out.println("3. Sort Song");
        System.out.print("Please Enter Choice: ");

        int userInput = console.nextInt(); // Get the data from user input

        switch (userInput)
        {
            case 1:
                this.songDatabase.addNewSong();
                break;

            case 2:
                this.songDatabase.removeSong();
                break;

            case 3:
                this.songDatabase.sortSongs();
                break;

            default:
                System.out.println("Please enter a valid number.");
                break;
        }
    }
}