Java 如何定义用户类以避免NullPointerException?

Java 如何定义用户类以避免NullPointerException?,java,Java,我是一名JAVA新手,曾试图找到答案,但一直在努力,因为我真的不知道如何使用正确的术语,而且在JAVA上编写的内容非常多。因此,如果在某个地方有人引用我的问题,但我一直找不到,我提前表示歉意 我有一个关于在JavaGUI中定义用户类的问题。我想编写一个使用我的对象的GUI,这些对象是定义的,它们基本上包含一些数字,是以前对对象的操作的结果 然而,在尝试实现这一点的过程中,我将问题细化为试图理解如何在一个地方定义类,并在另一个地方对它们进行操作 例如 public class Form exten

我是一名JAVA新手,曾试图找到答案,但一直在努力,因为我真的不知道如何使用正确的术语,而且在JAVA上编写的内容非常多。因此,如果在某个地方有人引用我的问题,但我一直找不到,我提前表示歉意

我有一个关于在JavaGUI中定义用户类的问题。我想编写一个使用我的对象的GUI,这些对象是定义的,它们基本上包含一些数字,是以前对对象的操作的结果

然而,在尝试实现这一点的过程中,我将问题细化为试图理解如何在一个地方定义类,并在另一个地方对它们进行操作

例如

public class Form extends javax.swing.JFrame {

    /**
     * Creates new form Form
     */
    public TheOtherClass otherClass;

    public Form() {

        TheOtherClass otherClass = new TheOtherClass();

    }
}
我认为,如果您将类声明为实例变量,然后在构造函数中实例化它,那么当窗体存在时,对象将“存在”。但是,当我尝试在其他任何地方使用该对象时,我会得到一个
NullPointerException

我认为这是因为尽管对象是在类级别声明的,但它是在构造函数中创建的,并且在构造函数代码完成时被销毁。这是正确的吗

当我这样做的时候,它工作

public class Form extends javax.swing.JFrame {

    /**
     * Creates new form Form
     */
    TheOtherClass otherClass = new TheOtherClass();

    public Form() { }
}
这样行吗?有更好或更喜欢的方法吗? 有人能告诉我一个可能有用的参考资料或教程吗

干杯
P

这两种方法都很好,这是您的具体示例的偏好问题。但是,执行此操作时,您没有设置类的成员变量:

public Form() {
    TheOtherClass otherClass = new TheOtherClass();
}
您正在创建一个同名的新变量。将其更改为:

public Form() {
    this.otherClass = new TheOtherClass();
}

我认为您在第一段代码中遇到了垃圾收集(GC)

当您在构造函数中声明并实例化otherClass对象时,正如您所注意到的,在执行构造函数之后,GC将可以访问该对象。因为这是一种常见的方式来做它的贝娄

public class Form extends javax.swing.JFrame {

/**
 * Creates new form Form
 */
TheOtherClass otherClass =null;

public Form(TheOtherClass otherClass) {
this.otherClass = otherClass;
}

}

otherClass是一个实例变量,一旦定义它,它就会立即可用。然而,在第一个代码块中,您声明了它,但没有实例化它,因此Java将其值设置为默认值:null(对于所有非基元类型)。 在类构造函数中,您不会初始化它,但会初始化另一个同名变量,其作用域在构造函数中,正如@nickb所指出的

要在实例化表单时避免此空值,Java中有3种方法:

1) 立即声明并实例化(第二个代码块)

2) 在实例初始值设定项块中实例化它

public class Form extends javax.swing.JFrame {
    TheOtherClass otherClass;
    { otherClass = new TheOtherClass(); } //instance initializer block
} 
3) 在构造函数中实例化它

public class Form extends javax.swing.JFrame {
    TheOtherClass otherClass;
    public Form() {
        otherClass = new TheOtherClass();
    }
}    

在一个表单对象的实例化过程中,Java将按顺序经历这三点。

另一种(而不是绝对“更好”)方法是使用:将另一个类的实例作为构造函数参数传递给它,分配给字段,并检查它是否为空。这在某些方面更好,因为它放松了
表单
类与
其他类
类的耦合,从而提高了
表单
类等的可测试性;但是,它会增加您必须编写的代码量。“我认为您在第一段代码中面临垃圾收集(GC)。”不,事实并非如此。你为什么这么认为?这不是一个好的评论,只是说“不”,请让我知道什么是错的。我已经说出了我的想法。你的想法完全不正确。nickb的回答解释了这个问题。而您的“常用方法”很糟糕,因为它创建了另一个类的实例,然后立即用参数值覆盖它;您不必检查参数值是否为空。@Andy Turner他/她想到的是另一个类otherClass=new TheOtherClass();在构造函数内部(创建表单后本地otherClass有资格使用GC),GC的资格与此没有直接关系。成员变量为null的原因是它从未被赋值。
public class Form extends javax.swing.JFrame {
    TheOtherClass otherClass;
    public Form() {
        otherClass = new TheOtherClass();
    }
}