如何在Java中创建对象数组

5
我将尝试创建一个由子类定义的对象数组(我认为这是正确的术语)。我可以看到这个问题一直在出现,但实现仍然存在问题。
我的代码:
public class Test {

    private class MyClass {
        int bar = -1;
    }

    private static MyClass[] foo;

    public static void main(String args[]) {

        foo = new MyClass[1];
        foo[0].bar = 0;

    }       
}

出现错误信息:

主线程异常:“main”java.lang.NullPointerException。

为了更好地解释这个问题,我把它简单化:

public class Test {

    private static int[] foo;

    public static void main(String args[]) {

        foo = new int[1];
        foo[0] = 0;

    }       
}

看起来它应该可以工作。我只是看不到我两个例子之间的区别。(我知道我的第一个是无意义的,但MyClass最终会包含更多数据。)

我很确定问题已经在这里被问过,并得到了很好的解答。我认为我已经实现了这个解决方案:

MyClass[] foo = new MyClass[10];
foo[0] = new MyClass();
foo[0].bar = 0;

但是上面的第二行会出现错误

Test类型的封闭实例不可访问。

我知道ArrayList可能是一种前进的方式,但我正在努力理解其基本概念。

NB-可能有用的是,虽然我对编程非常熟悉,但Java是我第一次涉足面向对象编程。


1
Java教程中关于嵌套类的章节可能是一个有趣的阅读,可以了解内部类的基础知识。 - Alderath
4个回答

6

MyClass类是一个内部类,而不是子类。非静态内部类可以通过创建包含该内部类的类对象来访问。因此,如果您要访问内部类,必须首先创建外部类的对象。您可以通过以下方式完成:

Test t = new Test();
MyClass[] foo = new MyClass[10];
foo[0] = t.new MyClass();
foo.bar = 0;

我不确定那是否是我想要做的:Test是我的最高类,我不认为我想创建它的一个实例。谢谢关注。 - KDM
@KDM 如果您不想创建 Test 的实例,那么您可能需要将 MyClass 设为静态。 - Rahul Bobhate

3
你在最后遇到的问题(“没有封闭实例”)实际上与数组无关。尝试使用以下代码块替换最后一段代码:
 MyClass foo = new MyClass();

即使没有涉及到任何数组,你仍将收到完全相同的错误消息。
问题在于非静态内部类具有对其外部实例的隐式引用。由于您没有外部实例(您在静态上下文中,没有“this”),因此无法创建任何“MyClass”实例。
可能不需要/想要一个内部类,只需将其设置为static即可:
private static class MyClass

此外:你的代码之所以使用int可以正常工作,而使用MyClass会出错,是因为int[]保存的是intint是原始类型),而MyClass[]保存的是MyClass 引用MyClass是引用类型)。

3

为什么int可以工作,但MyClass不能:

来自这里

Data Type               Default Value (for fields)
byte                    0
short                   0
int                     0
long                    0L
float                   0.0f
double                  0.0d
char                    '\u0000'
String (or any object)  null
boolean                 false

在初始化数组时,所有元素都采用默认值。

因此,当您初始化int[]时,所有元素都为0,因此使用它或分配新值没有问题。

但是,当您初始化MyClass[]时,所有元素都是null,这在尝试访问其中一个元素的成员时会出现问题。

如果您不知道为什么访问null对象的成员无法工作,那么您可能需要退后2步并阅读一本Java书。

附加说明:

从技术上讲,这个:

int[] foo = new int[1];
foo[0] = 0;

实际上更像这样:
MyClass[] foo = new MyClass[10];
foo[0] = new MyClass();

注意:

MyClass[] foo = new MyClass[10];
foo[0].bar = 0;

由于您正在为元素分配一个新值,而不是访问元素的成员,因此会出现这种情况。

类型Test的未包含实例是不可访问的:

其他答案已经很好地解释了这个问题,这里有3个相关问题:

类型未包含实例是不可访问的。

类型Server的未包含实例是不可访问的

在Android中从另一个类调用方法时出现“类型未包含实例”错误


所有的答案都很棒,都很有用,但是这个答案对我目前的Java职业生涯来说最有意义! - KDM

0

在静态main方法中无法使用非静态内部类。

解决方案是将MyClass声明为private static class


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接