I have read here that in Java it is possible for two variables having same name but different type to co-exist in the same scope. What I mean is this
class test
{
private int x;
private double x;
}
But all java IDE do not allow such code. I want to know whether such a code is really syntactically correct, or simply the IDE do not allow such code to prevent ambiguity.
Anyway here is the extract from the website
"If you're lucky, you might be able to recompile the output from Jad. However, the Java VM has more lenient rules for variable naming than the Java language itself. For instances, a valid class file can have several variables named 'a', as long as they have different types. If you decompile such a class, the source code you get will not be valid.
JAD will usually rename the offending fields, and make a recompilable file... the only problem being that the recompiled file won't be compatible with the original classes."
As others said, illegal in Java, but legal in bytecode.
javac assert
assert
is a Java example which in Oracle JDK 1.8.0_45 generates multiple fields with the same name but different types. E.g.:
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;
}
}
The presence of assert
generates an bool $assertionsDisable
a synthetic field to cache a method call, see: https://stackoverflow.com/a/29439538/895245 for the details.
Then:
javac Assert.java
javap -c -constants -private -verbose Assert.class
contains the lines:
#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
Note how the constant table even reuses #12
as the variable name.
If we had declared another boolean however, it would not compile:
static final boolean $assertionsDisabled = false;
with error:
the symbol $assertionsDisabled conflicts with a compile synthesized symbol
This is also why it is a very bad idea to use field names with dollar signs: When should I use the dollar symbol ($) in a variable name?
jasmin
Of course, we can also try it out with 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
Which contains two static fields, one int
(I
) and one float
(F
), and outputs:
1
1.5
If works because:
getstatic
points to a Fieldref
structure on the constant tableFieldref
points to to a NameAndType
NameAndType
points to the type, obviouslySo to differentiate them, Jasmin simply uses two different Fieldref
with different types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With