publicclass SpecialInterfaceCall { interface I1 { defaultvoid pub_m() {}; privatevoid priv_m() {};
} interface I2 extends I1 { // This needs to be a public method to avoid access control issues, // but logically we treat it as private and emulate invokespecial // using MethodHandles. defaultvoid pub_m() {};
privatevoid priv_m() {};
staticvoid invokeDirect(I2 i) {
i.priv_m(); // generates invokespecial
} staticvoid invokeSpecialMH(I2 i) throws Throwable { // emulates behaviour of invokeDirect
mh_I2_priv_m_from_I2.invokeExact(i);
} // special case of invoking an Object method via an interface staticvoid invokeSpecialObjectMH(I2 i) throws Throwable { // emulates invokespecial of I1.toString on i, which resolves // to Object.toString
String s = (String) mh_I1_toString_from_I2.invokeExact(i);
} // special case of invoking a final Object method via an interface staticvoid invokeSpecialObjectFinalMH(I2 i) throws Throwable { // emulates invokespecial of I1.getClass on i, which resolves // to Object.getClass Class<?> c = (Class<?>) mh_I1_getClass_from_I2.invokeExact(i);
}
} interface I3 extends I2 { // Must take an I3 here rather than I2 else we get // WrongMethodTypeException: expected (I3)void but found (I2)void // Statically the receiver type is bounded by the caller type. staticvoid invokeSpecialMH(I3 i) throws Throwable { // emulates an invokespecial of ((I2)i).pub_m()
mh_I2_pub_m_from_I3.invokeExact(i);
}
} // This interface acts like I2 but we define directInvoke* methods // that we will rewrite the bytecode of to use invokespecial // (see SpecialInterfaceCallI4.jasm). interface I4 extends I1 { staticvoid invokeDirect(I4 i) { // invokeSpecial Object.toString() thrownew Error("Class file for I4 is not overwritten");
} staticvoid invokeDirectFinal(I4 i) { // invokeSpecial Object.getClass() - final method thrownew Error("Class file for I4 is not overwritten");
}
}
// Classes that don't implement I2/I3 but do have a // priv_m/pub_m method in their hierarchy staticclass D1 implements I1 { } staticclass E { publicvoid pub_m() {} privatevoid priv_m() {}
}
// This MH acts like the direct invokespecial in I2.invokeDirect staticfinal MethodHandle mh_I2_priv_m_from_I2;
// This MH acts like an invokespecial of I2.pub_m from I3 staticfinal MethodHandle mh_I2_pub_m_from_I3;
// This MH acts likes an invokespecial of I1.toString from I2 staticfinal MethodHandle mh_I1_toString_from_I2;
// This MH acts likes an invokespecial of I1.getClass from I2 staticfinal MethodHandle mh_I1_getClass_from_I2;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.10Bemerkung:
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.