Closed glenn-syj closed 4 months ago
java 소스코드가 바이트 코드로 어떻게 변환되는지 확인할 수 있는 곳을 찾지 못해 궁금했었는데, 첨부해주셔서 감사합니다!
제네릭 T가 Object로 사용되는 것은 몇몇 설명에서 발견할 수 있었지만, next
가 extends Node<T>
로 표현된 것은 신기하네요
말씀하신 바와 같이 하위클래스도 해당 변수의 값으로 사용될 수 있다는 것이 명시적으로 보여지는 부분 같습니다.
글로만 읽을 때보다 코드를 직접 확인하니 보다 명확히 알수 있어 도움이 되었습니다. 부가설명 감사합니다!
Based on: #126 by @yngbao97
바이트코드를 통한 타입 소거 이해
들어가며
Oracle의 공식 자료를 참고해서 코드를 잘 작성해주셔서, 이번에는 java 소스코드가 바이트코드에서 어떻게 읽히는지 한 번 쯤 살펴보면 좋을 것 같았습니다.
자바 코드
Oracle 공식 문서에 기반하는, 제네릭을 이용한 클래스 구현입니다. 필드
data
와next
만이 아니라, 메서드getData()
의 반환 타입에서도 제네릭이 쓰이고 있습니다. 타입만이 아니라 메서드에서도 타입 소거는 이루어지고 있습니다.바이트코드
간단하게 살펴보자면, declaration이나 signature에는
<T>
가 명시되지만 실제 바이트코드에서는T
가 소멸되어Object
로 이용되고 있음을 알 수 있습니다. 대표적으로private Ljava/lang/Object; data
에서 확인할 수 있습니다.또한, 생성자의 declaration에서
// declaration: next extends java_test.Node<T>
부분도 흥미롭습니다. JVM은 생성자에서next
가 단순히Node<T>
타입이 아니라, 이를 상속하는 타입을 받도록 지시하고 있습니다. 즉, 하위 클래스인 인자가 자동으로 상위 클래스로 형변환되는 방식에 대한 서술으로 보입니다. 비록 깊게 알고 있지는 않지만, 단순히 구현하던 것과 달리 바이트코드에서는 동작 원리를 알게 되니 더욱 직관적으로 이해가 되네요.References
https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms-4.10.2.2