Java: имеет ли класс Object конструктор?
Javadoc упоминает, что класс Object имеет открытый конструктор no-arg. Но исходный код объекта не содержит в нем явного конструктора. Поэтому, очевидно, компилятор создал для него. Однако, если я вижу трассировку стека вызовов, когда конструктор вот-вот вернется (как показано ниже), я не вижу никакого вызова Object.<init>
в этой трассе.
Итак, вопрос в том, имеет ли класс Object конструктор по умолчанию, как говорит doc? Если да, то почему я не вижу его в трассировке стека вызовов?
public ConTest()
{
new Throwable().printStackTrace();
}
Результат:
java.lang.Throwable
at ConTest.<init>(ConTest.java:8)
at ConTest.main(ConTest.java:16)
Ответы
Ответ 1
Супер конструкторы запускаются до конструкторов sub/base. В вашем примере Object конструктор уже запущен, когда выполняется new Throwable().printStackTrace()
.
Более явная версия вашего кода:
public ConTest()
{
super();
new Throwable().printStackTrace(); // you will not see super() (Object.<init>) in this stack trace.
}
Ответ 2
Вы не видите его в трассировке стека, потому что он уже вызван. Исключение выбрано в вашем коде.
Ваш код эквивалентен записи:
public ConTest() {
super(); // this will call the Object constructor
new Throwable().printStackTrace();
}
Ответ 3
Вы не видите его в трассировке стека, потому что конструктор суперкласса вызывается перед вызовом new Throwable().printStackTace()
. Фактически создается компилятор.
public ConTest()
{
super(); // This is the call to the base class constructor
new Throwable().printStackTrace(); // already back from the base class constructor
}
Ответ 4
Да, класс объекта имеет конструктор по умолчанию, о котором говорит документ.
Как вы знаете, вы можете проверить это, используя javap -c ConTest в командной строке
вы можете увидеть, что он вызывает конструктор по умолчанию класса объекта() в нижнем коде Линия №: 1
C:\stackdemo>javap -c ConTest
Compiled from "ConTest.java"
public class ConTest extends java.lang.Object{
public ConTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: new #2; //class java/lang/Throwable
7: dup
8: invokespecial #3; //Method java/lang/Throwable."<init>":()V
11: invokevirtual #4; //Method java/lang/Throwable.printStackTrace:()V
14: return
public static void main(java.lang.String[]);
Code:
0: new #5; //class ConTest
3: dup
4: invokespecial #6; //Method "<init>":()V
7: astore_1
8: return
}
Спасибо
Ответ 5
Как указано выше, super() является первым вызовом в конструкторе и методе. Дополнительная информация здесь
Когда вы компилируете класс, компилятор Java создает метод инициализации экземпляра для каждого конструктора, который вы объявляете в исходном коде класса. Хотя конструктор не является методом, метод инициализации экземпляра. Он имеет имя <init>
, тип возвращаемого значения, void и набор параметров, которые соответствуют параметрам конструктора, из которого он был сгенерирован.