- Published on
바이트코드로 보는 Java 클래스 기본 생성자와 메소드 반환문
- Authors
- Name
- 신주용
기본 생성자 (default constructor)
모든 자바 클래스에는 적어도 하나 이상의 생성자가 정의되어야 합니다.
// 생성자 없음
class A {
}
// 기본 생성자
class B {
public B () {}
}
생성자의 특징
- 생성자의 이름은 클래스 이름과 동일해야 하고, 반환 타입을 가지면 안됩니다(
void
도). - 하나의 클래스 안에 같은 수와 타입의 인자를 갖는 생성자를 여러 개 추가할 수 없습니다.
- 생성자는 객체가 생성될 때 호출됩니다.
- 생성자를 명시적으로 정의하지 않았다면, 자바 컴파일러가 자동으로 기본 생성자를 추가해 줍니다.
기본 생성자 자동 추가
이번 포스팅에서는 4번 단계를 깊게 살펴봅니다. 우선, 임의의 클래스 Gumi
를 작성했습니다. Gumi
클래스는 생성자가 정의되지 않은 상태입니다. 추가로, return
이 없는 void 메소드 a()
도 있습니다.
public class I {
public static void main(String[] args) {
Gumi gumi = new Gumi();
}
}
class Gumi {
void a() {
}
}
자바는 우리가 작성한 코드를 바이트코드라는 중간 언어로 먼저 컴파일한 후, 이를 JVM에서 실행합니다. 생성자를 정의하지 않은 클래스를 컴파일하면 자바 바이트코드에는 어떻게 표현되는지를 알아보기 위해 javap
명령어를 사용해봅시다3.
$ javac I.java
$ ls
Gumi.class I.java I.class
$ javap -v Gumi.class
Classfile /.../Gumi.class
Last modified Jul 22, 2023; size 222 bytes
MD5 checksum eb6c509a700b5264c73e4275c16a4722
Compiled from "I.java"
class Gumi
minor version: 0
major version: 52
flags: ACC_SUPER
Constant pool:
#1 = Methodref #3.#11 // java/lang/Object."<init>":()V
#2 = Class #12 // Gumi
#3 = Class #13 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 a
#9 = Utf8 SourceFile
#10 = Utf8 I.java
#11 = NameAndType #4:#5 // "<init>":()V
#12 = Utf8 Gumi
#13 = Utf8 java/lang/Object
{
Gumi();
descriptor: ()V
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
void a();
descriptor: ()V
flags:
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 9: 0
}
SourceFile: "I.java"
major version: 52
: 자바 1.8 버전을 사용했습니다.Gumi(); descriptor: ()V
: 자동으로 추가된 기본 생성자입니다. 파라미터가 없고, 반환 타입은Void
입니다4.Gumi(); Code: ... 1: invokespecial #1 // Method java/lang/Object."<init>":()V
: 자바의 모든 클래스는Object
클래스를 상속합니다. 이 부분을 자바 코드로 표현하자면 다음 코드와 같습니다.class Gumi extends Object { public Gumi () { super(); } }
void a(): descriptor: ()V
: a() 메소드도 우리가 처음 자바코드에 작성한 것처럼 반환값이void
타입인 메소드입니다.void a(): Code: 0: return
: 여기에서도 자바 소스코드에서는 return문을 안 적었으나 자바가 자동으로 추가해준 것을 확인할 수 있습니다.
결과
이 결과를 통해
- 클래스에 생성자가 명시적으로 정의되어 있지 않다면 자바가 자동으로 기본 생성자를 추가해 주는 것을 확인했고,
- 반환값이 void 타입인 메소드여서 return을 안 적었더라도 이 또한 자동으로 추가해 주는 것을 확인할 수 있었습니다.
Footnotes
W3Schools "Java Constructors." www.w3schools.com. https://www.w3schools.com/java/java_constructors.asp (accessed Jul. 22, 2023). ↩
Oracle. "Providing Constructors for Your Classes." docs.oracle.com. https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html (accessed Jul. 22, 2023). ↩
Anshul Bansal. "View Bytecode of a Class File in Java." www.baeldung.com. https://www.baeldung.com/java-class-view-bytecode (accessed Jul. 22, 2023). ↩
Oracle. "Field Descriptors." docs.oracle.com. https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3 (accessed Jul. 22, 2023). ↩