Java에서는 인자없는 생성자(디폴트 생성자라고 합니다)가 있습니다. 이것은 명시적으로 지정하지 않는 경우 바이트코드 컴파일타임에 자동으로 inlined 됩니다.
class A
{
}
여기서 우리 눈에 보이지 않지만,
컴파일러는 다음과 같은 코드를 컴파일 시간에 추가합니다.
----------------------------
import java.lang.*;
class A extends Object
{
public A() {
super();
}
}
----------------------------
굵게 표시한 부분은 자동으로 추가되는 내용입니다.
왜 그럴까요? 언어 스펙이 그렇게 규정하기 때문입니다.
구지 부연설명을 드려보자면...,
(1) extends Object의 추가:
자바의 클래스 hierarchy상의 최상위 노드는 java.lang.Object입니다. 모든 자바 클래스는 java.lang.Object를 상속하도록 되어 있습니다.
명시적으로 extends java.lang.Object를 선언해주지 않으면 자동으로 추가되도록 되어있죠. 그래야 말이 되겠죠?
몇가지 중요한 사실이 많이 있습니다. 예를 들어... 명시적으로 임의의 클래스를 상속하면, extends Object 구문은 필요없어집니다.
class A extends B {
}
위와 같은 경우가 그렇죠. 이미 B가 Object를 상속하고 있을 것이므로 또다시 Object를 상속할 필요가 없고, 더구나 Java는 다중상속 자체가 구문오류를 나타내기 때문에 extends 키워드를 두번 이상 기술할 수 없습니다.
(2) 디폴트 생성자의 자동 생성:
디폴트 생성자가 자동으로 생성되는것은.. 개발자가 명시적으로 선언한 생성자가 하나도 없을 경우입니다. 예를 들어 인자있는 임의의 생성자를 선언하면, 컴파일러는 디폴트 생성자를 만들어주지 않습니다... 등등.
(3) 디폴트 생성자에서 암시적으로 슈퍼클래스의 생성자 호출(super();):
클래스 템플릿에 따라 객체가 인스턴스화 될 때에는, 상속 트리를 따라 최상위 노드까지의 모든 객체가 메모리에 생성됩니다. 예를 들어,
class A {
}
위의 클래스 정의가 있을 때, new A();는 Heap에 java.lang.Object의 인스턴스와 A의 인스턴스를 모두 만듭니다. 물론 java.lang.Object가 먼저 생성되어야 하기 때문에, 모든 생성자에는 super(); 코드가 숨겨져 있는 것입니다.
..........
nested class(non static), inner class(static) 등도 마찬가지 입니다. 중요한 개념이지만, 잘 사용하지 않다 보니 모르는 경우가 많습니다(중급 이상의 개발자의 웃지 못할 코딩을 발견하는 경우도 종종 있지요).
class A {
int i;
class AA {
{
A.this.i = 1;
}
}
}
class A {
static class B {
}
}
class A {
interface B {
}
}
......