繁体   English   中英

为属性创建构造函数与仅创建属性并使用默认构造函数

[英]Creating constructor for attributes vs. just creating attributes and using the default constructor

我想知道当我创建一个关于效率和内存使用的新对象时,两个代码段之间有什么区别。

private Node head;
private int size;

public MyLinkedList(){
    head  = new Node(0,null);
    size = 0;
}

private Node head= new Node(0,null);
private int size = 0;

public MyLinkedList(){

}  

编译对象时,编译器将为构造函数创建一个instance initialization method ,例如,为类MyLinkedList创建一个instance initialization method ,编译器将为类的两个版本创建该方法,如下所示:

public void <init>(MyLinkedList this) {...}

当您使用new关键字或MyLinkedList.class.newInstance()方法时,将调用此方法。

此外,有三种方法可以初始化您的对象:

  • 实例变量初始化(如上面的第二个版本)
  • 实例初始化(如下所示)
  • 构造函数(如您上面的第一个版本)

实例初始化:

private Node head;
private int size;

{
    Node = new Node(0,null);
    int = 0;
}

public MyLinkedList(){

}

编译器会将实例变量初始化代码,实例初始化代码和构造函数主体代码放在<init>方法中。 创建新实例时,编译器要做的第一件事是通过将实例变量初始化为其默认值来为Object及其所有实例变量分配内存。 此后,调用<init>方法。 Java语言规范中概述了确切的顺序:

这意味着在效率和内存使用上没有区别,使用哪种选择取决于您的用例和结构,例如,对于多个构造函数,您可能必须复制初始化代码或确保调用其他构造函数,使用实例初始化,您可以捕获异常或进行其他复杂的计算,而这些操作是实例变量初始化无法做到的。

为了进行验证,您可以安装Eclipse插件Bytecode Outline,并看到生成的字节码指令及其在类的两个版本中的顺序实际上是相同的:

MyLinkedList类的两个版本的字节码比较

在调用构造函数时,

在情况1中:仅当调用重写的默认构造函数时,两个变量才会初始化

在情况2中:调用任何其他构造函数将初始化两个变量。 即使这些构造函数中未提供任何初始化,也是如此。

因此,如果您只有一个构造函数(此默认构造函数),则它们的行为相同。 但是,如果您有其他构造函数,则行为会有所不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM