他の人が言ったように、Java では違法ですが、バイトコードでは合法です。
javac アサート
assert
は Java の例であり、Oracle JDK 1.8.0_45 で同じ名前でタイプが異なる複数のフィールドを生成します。例えば:
public class Assert {
// We can't use a primitive like int here or it would get inlined.
static final int[] $assertionsDisabled = new int[0];
public static void main(String[] args) {
System.out.println($assertionsDisabled.length);
// currentTimeMillis so it won't get optimized away.
assert System.currentTimeMillis() == 0L;
}
}
が存在すると、メソッド呼び出しをキャッシュする合成フィールドがassert
生成されます。詳細については、 https ://stackoverflow.com/a/29439538/895245を参照してください。bool $assertionsDisable
それで:
javac Assert.java
javap -c -constants -private -verbose Assert.class
次の行が含まれます。
#3 = Fieldref #9.#28 // Assert.$assertionsDisabled:[I
#5 = Fieldref #9.#31 // Assert.$assertionsDisabled:Z
#12 = Utf8 $assertionsDisabled
#28 = NameAndType #12:#13 // $assertionsDisabled:[I
#31 = NameAndType #12:#14 // $assertionsDisabled:Z
public static void main(java.lang.String[]);
3: getstatic #3 // Field $assertionsDisabled:[I
10: getstatic #5 // Field $assertionsDisabled:Z
定数テーブル#12
が変数名として再利用されていることに注意してください。
ただし、別のブール値を宣言した場合は、コンパイルされません。
static final boolean $assertionsDisabled = false;
エラーあり:
the symbol $assertionsDisabled conflicts with a compile synthesized symbol
これは、フィールド名にドル記号を使用することが非常に悪い考えである理由でもあります:変数名でドル記号 ($) を使用する必要があるのはいつですか?
ジャスミン
もちろん、Jasmin で試すこともできます。
.class public FieldOverload
.super java/lang/Object
.field static f I
.field static f F
.method public static main([Ljava/lang/String;)V
.limit stack 2
ldc 1
putstatic FieldOverload/f I
ldc 1.5
putstatic FieldOverload/f F
getstatic java/lang/System/out Ljava/io/PrintStream;
getstatic FieldOverload/f I
invokevirtual java/io/PrintStream/println(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
getstatic FieldOverload/f F
invokevirtual java/io/PrintStream/println(F)V
return
.end method
int
1 つ( I
) と 1 つfloat
( )の 2 つの静的フィールドを含みF
、出力は次のとおりです。
1
1.5
次の理由で機能する場合:
getstatic
Fieldref
定数テーブルの構造体を指します
Fieldref
を指すNameAndType
NameAndType
明らかに型を指す
したがって、それらを区別するために、Jasmin は単純Fieldref
に異なるタイプの 2 つの異なるものを使用します。