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

时间:2016-09-29 12:17:25

标签: java

我是一名JAVA新手,并试图找到答案,但一直在努力,因为我真的不知道如何使用正确的术语,而且写在Java上的金额是巨大的。所以我提前道歉,如果有一个参考解释我的问题,但我还没有找到它。

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

然而,在试图达到目标时,我已经将问题提炼到试图理解如何在一个地方定义类并在另一个地方采取行动。

例如......

public class Form extends javax.swing.JFrame {

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

    public Form() {

        TheOtherClass otherClass = new TheOtherClass();

    }
}

我认为如果你将类声明为一个实例变量,然后在构造函数中实例化它,那么对象就会生存下来#34;形式生活。但是,当我尝试在其他任何地方使用该对象时,我得到NullPointerException

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

当我这样做时,它有效......

public class Form extends javax.swing.JFrame {

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

    public Form() { }
}

这样好吗?有更好或更好的方式吗? 有人可以请我参考可能有帮助的参考或教程吗?

干杯 P

3 个答案:

答案 0 :(得分:7)

这两种方法都很好,这是你的具体例子的优先选择。但是,执行此操作时,您没有设置类的成员变量:

public interface IData
{
}

public class Data : IData
{
}

public interface IDataProvider<TData> where TData : IData
{
    TData Data { get; set; }
}

public class DataProvider : IDataProvider<Data>
{
    public DataProvider(Guid id, Data data)
    {
        Data = data;
    }

    public Data Data { get; set; }
}

class Program
{
    static void Main()
    {
        var container = new Container(_ => _.Scan(x =>
        {
            x.WithDefaultConventions();
            x.AssemblyContainingType<IData>();
            x.ConnectImplementationsToTypesClosing(typeof(IDataProvider<>));
        }));

        // Exception happens here!
        var instance = container
            .With(Guid.NewGuid())
            .GetInstance<IDataProvider<Data>>();
    }
}

您正在创建一个名称相同的 new 变量。将其更改为:

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

答案 1 :(得分:1)

otherClass是实例变量,一旦定义就立即可用。但是,在第一个代码块中,您声明它但不实例化它,因此 Java将其值设置为默认值:null ,对于所有非基本类型)。 在类构造函数中,您没有对其进行实例化,但是您实例化另一个具有相同名称的变量,其范围在构造函数中,如@nickb所指出的那样。

要在实例化Form时避免使用null,您在Java中有3种方法:

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

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

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();
    }
}    

在Form对象的实例化过程中,Java将按顺序通过3个点。

答案 2 :(得分:0)

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

当您在构造函数中声明并实例化otherClass对象时,您注意到在执行构造函数后,对象将可以在GC中访问。因为这种常见的方式可以如下所示。

public class Form extends javax.swing.JFrame {

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

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

}