按类构造函数初始化Java数组(性能问题)
假设我有A类和B类,代码是这样的:按类构造函数初始化Java数组(性能问题),java,arrays,Java,Arrays,假设我有A类和B类,代码是这样的: class A { private int x; private int[] y=new int[10]; private string s; } public class B { public static void main(String args[]) { A a=new A(); } //Auto generated constructor A() { x=0; s=NULL; y[]=//What wil
class A
{
private int x;
private int[] y=new int[10];
private string s;
}
public class B
{
public static void main(String args[])
{
A a=new A();
}
//Auto generated constructor
A()
{
x=0;
s=NULL;
y[]=//What will come here
}
我的理解是,当类A没有定义构造函数时,JVM会自动定义这样一个构造函数:
class A
{
private int x;
private int[] y=new int[10];
private string s;
}
public class B
{
public static void main(String args[])
{
A a=new A();
}
//Auto generated constructor
A()
{
x=0;
s=NULL;
y[]=//What will come here
}
我想知道在这个自动生成的构造函数中将为数组数据类型分配什么值。如果它为所有占位符分配零,这不会影响大型数组的程序性能,因为为数组的所有成员分配零在时间上不是一项便宜的任务 注:(更新) 它不存储空值。
它存储零。所以我的问题是它会影响大型阵列的性能。它将为空。数组被视为对象 如果您初始化一个数组(
int[]a=new int[10]
),它将用它们的默认值填充元素(例如int为零,对象和数组为null)
但是,默认构造函数不这样做。它只是将整个数组设置为null。它将为null。数组被视为对象 如果您初始化一个数组(
int[]a=new int[10]
),它将用它们的默认值填充元素(例如int为零,对象和数组为null)
但是,默认构造函数不这样做。它只是将整个数组设置为null。如果不这样初始化数组
private int[]y
它将返回null,但使用new,比如private int[]y=new int[10]
它用数组类型的默认值填充数组(在本例中为int)如果您没有像这样初始化数组private int[]y
它将返回null,但使用new,像这样private int[]y=new int[10]代码>它用数组类型的默认值填充数组(在本例中为int)我通过调试对此进行了检查
它将是[0,0,0,0,0,0,0,0,0,0]
,因为您设置了(初始化数组)private int[]y=new int[10]代码>
如果不这样初始化此数组,则它将是null
对于您的性能问题,请检查此项。我通过调试检查了此项
它将是[0,0,0,0,0,0,0,0,0,0]
,因为您设置了(初始化数组)private int[]y=new int[10]代码>
如果不这样初始化此数组,则它将是null
对于性能问题,请勾选此项。在java中,所有基本类型都将初始化为其默认值。因此,如果您使用其大小定义int类型的数组,那么所有值都将初始化为0。基本类型的开销比类小。在java中,所有基本类型都将初始化为默认值。因此,如果您使用其大小定义int类型的数组,那么所有值都将初始化为0。与类相比,基元类型的开销更小。来自此测试类:
public class Test {
int[] x;
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
您将获得以下输出:
null
如果在编译成字节码之前使用javac-XD printflat
查看编译器对源代码的操作,您会得到以下结果:
public class Test {
public Test() {
super();
}
int[] x;
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
由于x
从未直接初始化,因此它将为null
(目前找不到相关的JLS段落,但也许我会在某个时候偶然发现它。)
如果您将x
初始化为new int[10]
,则在编译为字节码之前,您将得到此已处理的源代码:
public class Test {
public Test() {
super();
}
int[] x = new int[10];
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
因此,在任何情况下,该字段都是作为独立于构造函数主体其余部分的步骤初始化的。JLS 12.5明确规定了这一点——实例初始值设定项和实例变量初始值设定项与构造函数的其余部分在单独的步骤中执行
但是,如果您使用new int[size]
显式初始化数组,您将得到一个包含所有0的数组,如您所述。这是否是一个性能问题实际上是一个没有实际意义的问题,因为JLS明确指定了阵列的默认值是什么,并且您将无法避免性能问题(如果有)。我现在正在查看JDK源代码,看看是否可以找到数组是如何创建的,但我怀疑您最不关心的应该是大型数组创建开销…来自此测试类:
public class Test {
int[] x;
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
您将获得以下输出:
null
如果在编译成字节码之前使用javac-XD printflat
查看编译器对源代码的操作,您会得到以下结果:
public class Test {
public Test() {
super();
}
int[] x;
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
由于x
从未直接初始化,因此它将为null
(目前找不到相关的JLS段落,但也许我会在某个时候偶然发现它。)
如果您将x
初始化为new int[10]
,则在编译为字节码之前,您将得到此已处理的源代码:
public class Test {
public Test() {
super();
}
int[] x = new int[10];
public static void main(final String[] args) {
System.out.println(new Test().x);
}
}
因此,在任何情况下,该字段都是作为独立于构造函数主体其余部分的步骤初始化的。JLS 12.5明确规定了这一点——实例初始值设定项和实例变量初始值设定项与构造函数的其余部分在单独的步骤中执行
但是,如果您使用new int[size]
显式初始化数组,您将得到一个包含所有0的数组,如您所述。这是否是一个性能问题实际上是一个没有实际意义的问题,因为JLS明确指定了阵列的默认值是什么,并且您将无法避免性能问题(如果有)。我现在正在查看JDK源代码,看看是否可以找到数组是如何创建的,但我怀疑,大的数组创建开销应该是您最不关心的问题…与任何其他对象一样--null
。你知道你可以自己试试,对吧?如果您担心初始化数组所需的时间,那么您也可能过早地进行了优化,如果这需要任何时间的话。是的,我可以,但我想知道它将如何运行