为什么它显示NullPointerException?

Joh*_*nna -2 java

我有一个学生的对象; 有一些字段,如姓名,家庭,...我想为这个学生创建一个用户名,点击一个按钮,我想在控制台上显示学生的用户名,但它会在控制台上显示这些句子(我复制并粘贴了其中的一部分)----->

显示java.lang.NullPointerException在registration.Students.nextUserName(Students.java:149)在ui.AddStudent.submit(AddStudent.java:254)在ui.AddStudent.jButton1ActionPerformed(AddStudent.java:186)在ui.AddStudent.access $ 000(AddStudent.java:24)在ui.AddStudent $ 1.actionPerformed(AddStudent.java:76)在javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)在javax.swing.AbstractButton中$ Handler.actionPerformed(AbstractButton中.的java:2318)在javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)在javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)在javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java :236)在java.awt.Component.processMouseEvent(Component.java:6038)在javax.swing.JComponent.processMouseEvent(JComponent.java:3265) ...

我的学生课程的一部分,也扩展了人类:

    public String nextUserName() {
    StringBuffer user = new StringBuffer();
    SystemManagement students = new SystemManagement();
    String name1 = students.getName();
    char char1 = name1.charAt(0);
    String family1 = students.getFamily();
    char char2 = family1.charAt(1);
    setUserName(name1 + "." + family1);
    if (user.length() != 0 && user.toString().equals(getUserName())) {
        char[] allowedCharacters1 = {char1, char2, '1', '.'};
        SecureRandom random = new SecureRandom();

        for (int i = 0; i < user.length(); i++) {
            user.append(allowedCharacters1[random.nextInt(allowedCharacters1.length)]);
        }
        setUserName(user.toString());
    }

    return getUserName();

}

public String currentUserName() {
    return getUserName();
}

public static Students getInstance() {
    if (instance == null) {
        instance = new Students();
    }
    return instance;
}
Run Code Online (Sandbox Code Playgroud)

我的人类:

 private String userName;

 public Human(String userName) {

    this.userName = Students.getInstance().nextUserName();
}

public void setUserName(String userName) {

    this.userName = userName;
}

public String getUserName() {
    return userName;
}
Run Code Online (Sandbox Code Playgroud)

谢谢我已将我的netUserName()方法更改为此但它返回null而不是异常.

public String nextUserName() {
  StringBuffer user = new StringBuffer();
  SystemManagement students = new SystemManagement();
  String name1 = students.getName();
  String family1 = students.getFamily();
  if(name1 !=null && family1 !=null ) {
    char char1 = name1.charAt(0);  
    char char2 = family1.charAt(1);
    setUserName(name1 + "." + family1);
    if (user.length() != 0 && user.toString().equals(getUserName())) {
      char[] allowedCharacters1 = {char1, char2, '1', '.'};
      SecureRandom random = new SecureRandom();
      for (int i = 0; i < user.length(); i++) {
        user.append(allowedCharacters1[random.nextInt(allowedCharacters1.length)]);
      }
      setUserName(user.toString());
    }
  }
  return getUserName();
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*edy 10

它显示是NullPointerException因为你在第149行有一个空指针.我不知道哪一行是第149行,所以让我们考虑一下这些选项:

StringBuffer user = new StringBuffer();
Run Code Online (Sandbox Code Playgroud)

不能那样.它正在创建一个新对象.

SystemManagement students = new SystemManagement();
Run Code Online (Sandbox Code Playgroud)

出于同样的原因,也不能成为那条线.(虽然我很困惑系统管理是什么,为什么"学生"会成为这样一个对象的好名字.)

String name1 = students.getName();
Run Code Online (Sandbox Code Playgroud)

不能那样.我们已经知道students不能为null(否则前一行会抛出一个不同的异常而不允许执行到达这一行).

char char1 = name1.charAt(0);
Run Code Online (Sandbox Code Playgroud)

也许那个.使用调试器检查值name1.它是空的吗?您希望从全新的系统管理中获得什么名称?

String family1 = students.getFamily();
Run Code Online (Sandbox Code Playgroud)

不可能是那一个.

char char2 = family1.charAt(1);
Run Code Online (Sandbox Code Playgroud)

也许那个.您对全新的系统管理有何期待?

setUserName(name1 + "." + family1);
Run Code Online (Sandbox Code Playgroud)

不能是这一个.如果这两个字符串变量中的任何一个为null,那么当你调用charAt它们时,你就会得到更早的异常.

该行之后的所有内容要么使用两个字符串对象,要么使用新创建的对象,因此我们可以不考虑方法的其余部分.把注意力集中在我指出的两条线上(或者你知道的第149条线).


在使用它们之前,您已经更改了代码以检查name1并且family1不是null,但我认为您并未真正考虑过潜在的问题.什么是新的SystemManagement 应该为您提供用户名和姓氏?他们将永远是任何其他比空?

显然,这些值中的一个或两个都是null,因此您可以跳过方法中的所有其他内容,直到您调用的最后一行getUserName.既然你已经跳过了这个号码setUserName,那么getUserName应该返回什么价值呢?(如果你不知道,那就去找吧.)

当你问"为什么我的程序会做X?" 回答另一个问题:"为什么应该做X?" 你是编写代码的人,所以程序最终完全按照你的要求去做.如果它没有达到您的预期,那么您就给出了错误的指示.如果必要的话,一次一行地查看代码,并找出出错的地方.确保您确切了解代码的每一行将执行的操作.如果您有一条线并且您不理解它,请阅读文档,询问您的教师,或在此处询问.在纸上执行,跟踪每个变量的值,并在重新分配它们时划掉旧值.如果您有多个类的实例,请确保在任何给定时间跟踪您正在使用的实例.

(总有一天,你会打一个问题,这是外部因素造成的.一个有错误的编译器,坏RAM,执行不力的规格等今天不是那一天.如果你怀疑任何这些,请确保您已要先彻底排除了任何可能是你自己的错误.)