, 10% - , - .
, boolean ( return , boolean). boolean, , .
static boolean isOddAndShort(int i) {
return (i&1)!=0 && (i>>>16)==0;
}
static boolean isOddAndShort(int);
descriptor: (I)Z
flags: ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: iconst_1
2: iand
3: ifeq 17
6: iload_0
7: bipush 16
9: iushr
10: ifne 17
13: iconst_1
14: goto 18
17: iconst_0
18: ireturn
, and, .
static void evenOrOdd(int i) {
System.out.println((i&1)!=0? "odd": "even");
}
static void evenOrOdd(int);
descriptor: (I)V
flags: ACC_STATIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: iload_0
4: iconst_1
5: iand
6: ifeq 14
9: ldc #3 // String odd
11: goto 16
14: ldc #4 // String even
16: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
19: return
.
( , i&1, , ).
, , . 0,01% ( ) 10% - , , 0,001% ( ).
, (, ), ASM:
, place-holder, i2b, int to boolean (). , :
public class Example {
private static boolean i2b(int i) {
return i!=0;
}
public static boolean isOdd(int i) {
return i2b(i&1);
}
public static void run() {
for(int i=0; i<10; i++)
System.out.println(i+": "+(isOdd(i)? "odd": "even"));
}
}
public class Int2Bool {
public static void main(String[] args) throws IOException {
String clName = Example.class.getName();
ClassReader cr = new ClassReader(clName);
ClassWriter cw = new ClassWriter(cr, 0);
cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if(name.equals("i2b") && desc.equals("(I)Z")) return null;
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if(opcode == Opcodes.INVOKESTATIC && name.equals("i2b") && desc.equals("(I)Z"))
return;
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
};
}
}, 0);
byte[] code = cw.toByteArray();
if(writeBack(clName, code))
Example.run();
else
runDynamically(clName, code);
}
private static boolean writeBack(String clName, byte[] code) {
URL u = Int2Bool.class.getResource("/"+clName.replace('.', '/')+".class");
if(u==null || !u.getProtocol().equals("file")) return false;
try {
Files.write(Paths.get(u.toURI()), code, StandardOpenOption.TRUNCATE_EXISTING);
return true;
} catch(IOException|URISyntaxException ex) {
ex.printStackTrace();
return false;
}
}
private static void runDynamically(String clName, byte[] code) {
Class<?> rtClass = new ClassLoader() {
Class<?> get() { return defineClass(clName, code, 0, code.length); }
}.get();
try {
rtClass.getMethod("run").invoke(null);
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
}
public static boolean isOdd(int);
descriptor: (I)Z
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iload_0
1: iconst_1
2: iand
3: ireturn
. , , , .