创建属性的构造函数,只创建属性并使用默认构造函数

时间:2016-03-27 07:37:46

标签: java constructor

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

private Node head;
private int size;

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

VS

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

public MyLinkedList(){

}  

2 个答案:

答案 0 :(得分:3)

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

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 Language Specification

中列出

这意味着在效率和内存使用方面没有任何区别,并且考虑使用哪一个取决于您的用例和结构,例如:使用多个构造函数,您可能必须复制初始化代码或确保调用其他构造函数,通过实例初始化,您可以捕获异常或执行更多复杂的计算,否则您无法使用实例变量初始化。

要验证,您可以安装Eclipse插件Bytecode Outline并查看生成的字节码指令及其类的两个版本的顺序几乎相同:

Bytecode comparison of the two versions of the MyLinkedList class

答案 1 :(得分:1)

在调用构造函数时,

在案例1中:只有在调用被覆盖的默认构造函数时才初始化两个变量

在第2种情况下:调用任何其他构造函数将初始化这两个变量。即使这些构造函数中没有提供任何初始化。

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

相关问题