The valid values of booleans / bytes / shorts / chars are only enforced in the Java compiler, not actually in bytecode.
But the Java compiler assumes values will be in range - i.e. that a boolean will be zero or one, that sort of thing.
And as such it makes some optimizations that are... questionable, if you're interfacing with bytecode that wasn't produced by the Java compiler.
For example, if `flag` is supposedly a boolean, but you gave it the value `2` directly via bytecode, flag==true is false, as it gets compiled down to flag == 1, which is false, but flag?bar:baz will return bar.
This can seriously break static analysis, among other things.
As far as not catching checked exceptions goes, this is actually possible in the Java language as well since the language allows throwing a generic type parameter. It's pretty difficult to do by accident though, and does at least give a compile warning.
public class Dangerous {
public static void main (String ... args) {
Dangerous.<RuntimeException>throwUnchecked(new IOException("Forgot to catch me!"));
}
static <T extends Exception> void throwUnchecked(Exception e) throws T{
throw (T) e;
}
}
I knew the SO answer must have been written by Raf before I even got to the author section. Check out his great library, ByteBuddy, if you want to try mucking with some of this stuff:
If the Java Virtual Machines don't always execute certain Java Byte Codes, how does a compiler to JVB for another language know that the generated code is run ?
There's an official specification for what and how a program that claims to be a JVM implementation should operate given Java bytecode. So someone writing a language that compiles to Java bytecode would typically either target the specification (and test on as many implementations as they felt necessary), or target a specific implementation like HotSpot and ignore the rest.
class CovariantReturn extends CovariantReturnBase {
public Integer produce() {
return 5;
}
}
class CovariantReturnBase {
public Number produce() {
return 4.5;
}
}
And the relevant javap output for CovariantReturn:
public java.lang.Integer produce();
flags: ACC_PUBLIC
Code:
...
public java.lang.Number produce();
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
...