何时将对象分配给实例变量

时间:2013-08-14 05:48:27

标签: java

考虑一个简单的代码:

public class Graph {

    private final List<ArrayList<Integer>> adjList = new ArrayList<ArrayList<Integer>>();
    private final int vertexCount;
    private int edgeCount;

    public Graph(int vertexCount) {
        this.vertexCount = vertexCount; 
    }
}

我的问题是何时创建了adjList对象,换句话说何时将内存分配给adjList?

它是在构造函数调用之后(不太可能)?

之前(因为私有构造函数可以使用静态类吗?)

如果之前正好考虑代码构造如下:

Graph g = new Graph(10); 

4 个答案:

答案 0 :(得分:3)

jls-12.5 : Creation of New Class Instances

  

每当创建一个新的类实例时,为它分配内存空间,为类类型中声明的所有实例变量提供空间,并在类类型的每个超类中声明所有实例变量,包括可能的所有实例变量隐藏(§8.3)。

答案 1 :(得分:3)

了解adjList不是对象非常重要。这是一个变量 - 一个领域。 adjList变量的空间被分配为在创建Graph的实例时发生的第一个事件...在任何构造函数调用之前甚至开始。

接下来,VM遍历继承层次结构,评估所需的构造函数参数,直到它到达Object类,然后它执行构造函数的主体...然后堆栈弹出执行子类的构造函数体。所以如果你有:

class Foo extends Object
class Bar extends Foo

然后首先执行Object的构造函数体,然后Foo,然后Bar

只有在构造函数体执行时才执行实例初始值设定项。就在这个召唤发生的时候:

new ArrayList<ArrayList<Integer>>()

创建另一个对象,然后初始化程序将引用分配给adjList变量的新对象。重要的是要理解adjList的值不是对象 - 它是一个参考。所以现在有两个对象(一个Graph和一个ArrayList)以及Graph对象中ArrayList对象的引用。 (实际上ArrayList也会引用一个数组。)

答案 2 :(得分:0)

   private final List<ArrayList<Integer>> adjList = new ArrayList<ArrayList<Integer>>();
    private final int vertexCount;
    private int edgeCount;

    public Graph(int vertexCount) {
        this.vertexCount = vertexCount; 
    }

变为:

   private final List<ArrayList<Integer>> adjList;
    private final int vertexCount;
    private int edgeCount;

    public Graph(int vertexCount) {
        adjList = new ArrayList<ArrayList<Integer>>();
        edgeCount = 0;
        this.vertexCount = vertexCount; 

    }

在调用new之后立即分配默认内存,然后由JVM调用构造函数。从那里,所有实例变量都在构造函数中实例化。显式定义由编译器在构造函数体内移动。

答案 3 :(得分:0)

  

我的问题是何时创建了adjList对象,换句话说是什么时候   内存分配给adjList?

作为实例变量,它将在创建实例时创建。

  

是在构造函数调用之后(不太可能)?

它将作为构造函数调用的一部分创建,因为构造函数将确保根据实例变量在内存中创建对象。

  

之前(因为私有构造函数可以使用静态类吗?)

不,在构造函数调用之前只创建静态变量。加载类时会创建静态变量。