不在声明中时的数组初始化语法


141

我可以写:

AClass[] array = {object1, object2}

我也可以写:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

但我不能写:

AClass[] array;
...
array = {object1, object2};

为什么这会被Java阻止?

我知道如何解决它,但有时会更简单。

例如:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

自从我学会了如何在Java中玩数组以来,这个简单的问题一直困扰着我。


对不起文本格式,但是由于中国的某种原因,文本布局按钮没有显示:S
Jason Rogers

对于代码,只需确保缩进4个或更多空格即可。

另一个问题是您粘贴的代码中有TAB字符。这弄乱了格式。
斯蒂芬·C

好吧,谢谢,eclipse在缩进中使用了制表符,所以当我复制粘贴时,它使事情变得混乱了。感谢您的编辑
杰森·罗杰斯

可以并且应该将Eclipse 重新配置为不使用TAB字符进行缩进。请不要以此为借口。
斯蒂芬·C

Answers:


137

为什么这会被Java阻止?

您必须询问Java设计人员。该限制可能有一些微妙的语法原因。请注意,某些数组创建/初始化结构不在Java 1.0中,而(IIRC)是在Java 1.1中添加的。

但是“为什么”是无关紧要的……存在限制,您必须忍受它。

我知道如何解决它,但有时会更简单。

您可以这样写:

AClass[] array;
...
array = new AClass[]{object1, object2};

9
没有新的声明,语句块和数组初始值设定项之间没有区别(就像在javascript中一样,这可能会引起误解}
bestsss 2011年

10
令人困惑……并且难以解析。考虑一下if {o1()}是一个有效的表达式,{o1();}还是一个有效的语句块。解析器必须到达'}'或';' 在可以区分这两种情况之前。语法问题一点都不微妙!!
Stephen C

19

我将尝试回答“为什么”这个问题:与ArrayList之类的类相比,Java数组非常简单且基本,后者更具动态性。Java想在声明时知道应该为数组分配多少内存。ArrayList动态得多,其大小可以随时间变化。

如果用2的长度初始化数组,后来又发现需要3的长度,则必须扔掉已有的东西,然后创建一个全新的数组。因此是“ new”关键字。

在前两个示例中,您在声明时告诉要分配多少内存。在您的第三个示例中,数组名称完全变为无指针,因此,在对其进行初始化时,您必须显式创建一个新数组以分配正确的内存量。

我想说的是(如果有人知道的话,请纠正我)第一个例子

AClass[] array = {object1, object2}

实际上意味着

AClass[] array = new AClass[]{object1, object2};

但是Java设计人员所做的是,如果在声明时创建数组,则可以更快地编写它。

建议的解决方法是好的。如果时间或内存使用量在运行时很关键,请使用数组。如果不是很关键,并且您希望代码易于理解和使用,请使用ArrayList。


2
正如您在引用Oracle时所述,这是一个快捷方式:“或者,您可以使用快捷方式语法来创建和初始化数组”。原因可能是在某个时候必须使用new 给数组提供一定的内存空间。New在快捷方式中是隐式的,但是快捷方式仅在声明中有效。在其他地方,不允许使用任何快捷方式,并且必须提供新功能。
2014年

3
很抱歉,您尝试回答“为什么”问题的尝试没有成功。编译器将能够制定出数组有多大需要的是通过计算之间的表达式{}...就像它为允许在初始化的形式。
斯蒂芬·C

8

我无法回答“为什么”部分。

但是,如果您想要动态的东西,那为什么不考虑Collection ArrayList。

ArrrayList可以是任何对象类型。

而且如果作为强制将其作为数组,则可以在其上使用toArray()方法。

例如:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

希望对您有所帮助。


2
无需将Array的返回类型强制转换为String []。通过合同,返回的数组与指定数组的类型相同。docs.oracle.com/javase/6/docs/api/java/util/…–
Ankur Agarwal

4

对于那些不喜欢这种令人讨厌的new AClass[] { ... }语法的人来说,这里有些糖:

public AClass[] c(AClass... arr) { return arr; }

根据需要使用此小功能:

AClass[] array;
...
array = c(object1, object2);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.