생성자에 슈퍼 클래스 생성자 (또는 this()
)에 대한 명시 적 호출이 없으면 컴파일러는 super()
.
이 호출이 컴파일 후 클래스 파일에서 제거되면 어떻게됩니까?
나는 그것을 직접 시도했다.
class Test
{
public Test()
{
System.out.println("Hello World");
}
public static void main(String[] args)
{
new Test()
}
}
나는 그것을 컴파일 invokespecial java/lang/Object/<init>()V
하고 클래스 파일 편집기로 생성자에서 제거했습니다 .
JVM이 클래스로드를 거부하는 것 같습니다.
Exception in thread "main" java.lang.VerifyError: Operand stack overflow
Exception Details:
Location:
Test.<init>()V @4: ldc
Reason:
Exceeded max stack size.
Current Frame:
bci: @4
flags: { flagThisUninit }
locals: { uninitializedThis }
stack: { uninitializedThis, 'java/io/PrintStream' }
Bytecode:
0000000: 2ab2 0002 1203 b600 04b1
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
나는 그것이 정의 된 행동인지 아직도 모른다.
편집하다
Raedwald에 따르면 스택 조작도 변경해야합니다.
그래서 aload_0
슈퍼 생성자 호출 이전에 있던 것도 제거했습니다 .
이제 다음 예외가 발생합니다.
Exception in thread "main" java.lang.VerifyError: Constructor must call super()
or this() before return
Exception Details:
Location:
org/exolin/geno/Test.<init>()V @8: return
Reason:
Error exists in the bytecode
Bytecode:
0000000: b200 0212 03b6 0004 b1
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
이로 인해 호기심이 생겨 생성자 지침을 다음과 같이 재정렬했습니다.
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Message"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
aload_0
invokespecial java/lang/Object/<init>()V
return
작동했습니다!
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다