我正在线上学习Java教程,试图学习这门语言,并且它在两个使用数组的语义之间蹦蹦跳跳。
long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;
和
long results[] = {1, 2, 3};
教程从未真正提到为什么它在两者之间来回切换,所以我对这个主题进行了一些搜索。我目前的理解是new
运算符正在创建“longs数组”类型的对象。我不了解的是我为什么要这样做,有什么后果?
new
运算符初始化的对象,而这些对象通常不必执行此操作?我来自C,所以我的Java术语在这里可能不正确,所以如果某些事情不可理解,请要求澄清。
答案 0 :(得分:13)
在Java中,所有数组和对象都在堆上分配,因此从某种意义上说,所有数组都是"数组对象"。在Java中堆栈上唯一分配的东西是对象引用和原语。其他所有内容都是在堆中定义和分配的对象,包括数组,无论您使用哪种语法来声明它。 (您的两个示例在最终结果中是等效的,请参阅JLS §10.3及其链接部分,了解有关如何实际分配和分配每个示例的更多信息。)
这与C / C ++相反,在C / C ++中,您可以显式控制堆栈和堆分配。
请注意,Java在短期对象分配/释放方面非常快。由于其基于生成的垃圾收集器,它的效率很高。所以回答你的问题:
是否有某些"阵列"除非它是一个"数组对象,否则不会在数组上工作的特定方法"?有什么我可以用"数组对象"我可以使用普通数组吗?
没有数组这样的东西不是一个对象,所以没有。然而,是,这些方法不会对原始数组起作用。如果没有先将Object[]
转换为long[]
,则Long[]
的方法将无法接受new
。这是由于Java 5及更高版本中的自动装箱的一些实现细节。
Java VM是否必须清理使用
new
运算符初始化的对象,而这些运算符通常不必执行此操作?
使用malloc
分配的任何内容最终都必须进行垃圾回收,因此在执行任何操作时, 不是。但请注意,在C / C ++中,使用new
/ free
分配数组意味着您还需要delete []
/ long[]
,这是您不要必须用Java做,因为它会为你收回数组。
请注意,如果在方法中声明了delete []
,并且您从未将其存储在方法之外的某个引用中,则会在方法调用结束时自动将其标记为垃圾回收。垃圾收集器将等待回收它的空间直到它需要它,但你不必通过delete
(或{{1}}和对象的析构函数)自己进行任何回收。
编辑:承诺的一些参考文献:
答案 1 :(得分:7)
Java中的new
关键字创建一个新对象。在这种情况下,它正在创建一个数组......这是一个对象。
这两种形式是等价的。第二个是第一个方便的简写。它是语法糖。
是否有某些“数组”特定方法在数组上不起作用,除非它是“数组对象”?
所有数组都是对象。周期。
对于我可以用普通数组做的“数组对象”,我有什么不能做的吗?
见上文。
Java VM是否必须清理使用new运算符初始化的对象,而这通常不需要做?
没有。就JVM而言,以不同方式创建的对象之间没有区别。
答案 2 :(得分:5)
这两个在创建的数组的行为方面是相同的。所有数组在技术上都是java中的对象;这些只是初始化它们的两种不同方式。也可以将两者结合起来:
long[] results = new long[]{1,2,3};
答案 3 :(得分:3)
两者都是一样的。第二个选项是隐式创建数组对象,它只是为了方便用户。
答案 4 :(得分:3)
在Java编程语言中,数组是对象(§4.3.1),是动态创建的,可以分配给Object类型的变量(§4.3.2)。可以在数组上调用Object类的所有方法。
数组由数组创建表达式(第15.10节)或数组初始化程序(第10.6节)创建
来自15.10. Array Creation Expressions
数组创建表达式创建一个对象,该对象是一个新数组,其元素的类型由
PrimitiveType
或ClassOrInterfaceType
指定。
可以在声明(第8.3节,第9.3节,第14.4节)中指定数组初始值设定项,或者作为数组创建表达式(第15.10节)的一部分,以创建数组并提供一些初始值。
两者都是初始化数组,差异是第二个用一些值初始化。
答案 5 :(得分:1)
您展示的两种创作方式是等效的。两者都是“数组对象” - 请记住,Java中的所有内容(除int
,double
等基本数字类型外)都是对象。第二个是第一个的简写,就像C对堆栈分配的整数数组有类似的简写一样。
答案 6 :(得分:1)
以下两个代码段在编译级别上是等于的。 我写了一个Demo类,如:
public class NewArray {
public static void main(String[] args) {
long results[] = new long[3];
}
}
和
public class NewArray {
public static void main(String[] args) {
long results[] = {0,0,0};
}
}
输出' javap -c NewArray'完全一样:
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: newarray long
3: astore_1
4: return
}
长期结果[] = new long [] {1,2,3};结果很长[] = {1,2,3};也完全一样。
所以,虽然有时候你没有使用新的关键词,但编译会认为它们是相同的。
答案 7 :(得分:1)
'new'关键字创建一个数组。现在,根据数组的数据类型,它内部的值会有所不同。如果将数组声明为整数并使用'new'关键字,那么它将包含值0,除非您更改其中的值。使用String,它将包含值'null'。在每一个空间。
答案 8 :(得分:0)
在这两种情况下,您都可以创建一个对象。
在第一个版本中:
long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;
你在第一行说数组大小是3.然后你把值放到数组中。
第二版:
long results[] = {1, 2, 3};
您创建相同的数组并在同一行中初始化它。 Java计算,你提供了3个参数并在没有你帮助的情况下生成new long[3]
:)