자바 클래스 파일 형식을 배우려고하고 ConstantValue 속성 아래에 상수 변수 값이 저장되어 있다는 것을 알고 있습니다. 상수 필드 값은 클래스 파일에 저장됩니다. 예 :여기서 클래스 파일에 저장된 변수의 초기 값은 무엇입니까?
public Robot robot = new Robot();
나는 oracles 클래스 파일 사양을 검토 한 결과 이와 같은 속성을 찾을 수 없습니다.
자바 클래스 파일 형식을 배우려고하고 ConstantValue 속성 아래에 상수 변수 값이 저장되어 있다는 것을 알고 있습니다. 상수 필드 값은 클래스 파일에 저장됩니다. 예 :여기서 클래스 파일에 저장된 변수의 초기 값은 무엇입니까?
public Robot robot = new Robot();
나는 oracles 클래스 파일 사양을 검토 한 결과 이와 같은 속성을 찾을 수 없습니다.
초기 값을 저장하기위한 유일한 속성은 ConstantValue
입니다. 그러나 이것은 정적 변수에만 사용됩니다. 자바 컴파일 코드에서는 정적 최종 변수에만 사용되지만 필기 바이트 코드의 정적 변수에는 사용할 수 있습니다. 물론이 값은 일정해야합니다.
게시 한 예제의 경우, 사용자는 이니셜 라이저으로 알려져 있습니다. 이것들은 클래스 파일에는 해당하지 않습니다.대신 모든 수퍼 클래스 생성자 호출이 반환 된 후에 Java 컴파일러에서이 코드를 붙여 넣습니다. 이것은 수퍼 클래스 생성자에서 가상 메소드를 호출하는 것과 같이이 시점 이전에 볼 수있는 경우 아직 초기화되지 않았 음을 의미합니다.
다음은 예입니다.
public class initializers {
static final float f = 4;
static final int i = int.class.hashCode();
static int i2 = 4;
public final Object x = null;
public Object x2 = null;
public initializers() {}
public initializers(int x) {this();}
public initializers(float x) {}
}
컴파일하고 당신이 볼 수 있듯이
.version 49 0
.class super public initializers
.super java/lang/Object
.field static final f F = 4.0F
.field static final i I
.field static i2 I
.field public final x Ljava/lang/Object;
.field public x2 Ljava/lang/Object;
.method public <init> :()V
.limit stack 2
.limit locals 1
aload_0
invokespecial java/lang/Object <init>()V
aload_0
aconst_null
putfield initializers x Ljava/lang/Object;
aload_0
aconst_null
putfield initializers x2 Ljava/lang/Object;
return
.end method
.method public <init> : (I)V
.limit stack 1
.limit locals 2
aload_0
invokespecial initializers <init>()V
return
.end method
.method public <init> : (F)V
.limit stack 2
.limit locals 2
aload_0
invokespecial java/lang/Object <init>()V
aload_0
aconst_null
putfield initializers x Ljava/lang/Object;
aload_0
aconst_null
putfield initializers x2 Ljava/lang/Object;
return
.end method
.method static <clinit> :()V
.limit stack 1
.limit locals 0
getstatic java/lang/Integer TYPE Ljava/lang/Class;
invokevirtual java/lang/Object hashCode()I
putstatic initializers i I
iconst_4
putstatic initializers i2 I
return
.end method
에서 클래스 결과 분리력, f
는 ConstantValue
속성을 사용하는 유일한 하나입니다. i
은 상수 표현이 아니기 때문에 진수가 아니기 때문에 i2
은 최종이 아니기 때문에 진리가 아닙니다. i
및 i2
을 초기화하는 코드는 정적 초기화 프로그램 ('클래스 생성자')에 포함되었습니다. x
및 x2
을 초기화하는 코드는 두 개의 수퍼 클래스 생성자 호출 뒤에 붙여 넣었지만 두 번째 생성자에서는 동일한 클래스의 생성자를 호출하지 않았습니다.
@JB 당신 말이 맞아요, 그들은 공개 일 필요는 없습니다. – Antimony
붙여 넣은 코드에 상수가 없습니다. 변수가 있습니다 (런타임시 스택에 할당 됨).
정수 필드가 아닌 클래스의 바이트 코드에 관심이 있으시면 을 사용해보십시오.
변수 robot
은 런타임에 초기화됩니다. 말, robot
클래스 Foo
에 있습니다
class Foo {
public Robot robot = new Robot();
Foo() {
}
}
이제 자바 컴파일러는 다음 단계를 실행하는 일련의 명령에 new Foo()
변환합니다 :
Foo
을위한 공간을 할당합니다. 여기에는 필드 공백이 포함됩니다.robot
.Robot
Foo
Robot
Foo
그래서 바이트 코드에 무엇인가 결론은 바이트 코드에서 필드 로봇에 대한 공간이 없습니다 Robot
의 할당 및 초기화 Foo
값이 상수가 아니므로 클래스 파일에 저장할 수 없습니다. –