2013-08-14 3 views
1

Рассмотрим простой код:Когда объекты отнесены к переменным экземпляра, созданных

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); 

ответ

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 также будет иметь ссылку на массив.)

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

jls-12.5 : Creation of New Class Instances

Всякий раз, когда создается новый экземпляр класса, пространство памяти выделяется для него с комнатой для всех переменных экземпляра, объявленных в типе класса и всех переменных экземпляра, объявленных в каждом суперклассе типа класса , включая все переменные экземпляра, которые могут быть скрыты (§8.3).

0

Мой вопрос, когда создается объект adjList, другими словами, когда память выделяется adjList?

Будучи переменной экземпляра, она будет создана при создании экземпляра.

Это после вызова конструктора (маловероятно)?

Он будет создан как часть вызова конструктора, потому что конструктор обязательно создаст объект в памяти в соответствии с переменными экземпляра.

До (класс может быть статическим с частным конструктором)?

Нет, перед вызовом конструктора создаются статические переменные. Статические переменные создаются при загрузке класса.

+0

Нет, не после вызова конструктора - как * часть * вызова конструктора. –

+0

@JonSkeet Right Jon, как часть конструктора, спасибо! исправленный. –

Смежные вопросы