Это изменение обратно совместимо?
номер
Несмотря на то, что константы обычно встроены, поле все еще является частью файла класса, поэтому возможно, что какой-то динамический поиск ссылается на поле, используя его старый тип, который является int
. Например:
// defined in `MyClass`
static final byte x = 10;
public static void main(String[] args) throws Throwable {
lookup().findStaticGetter(MyClass.class, "x", int.class); // old code
}
Это выдает NoSuchFieldException
, так как поиск ищет старый тип поля.
Это также относится к API написания байт-кода, которые обращаются к полю, например, с ASM :
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(55, ACC_PUBLIC, "Test", null, "java/lang/Object", null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()V", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitFieldInsn(GETSTATIC, "MyClass", "x", "I"); // looking for int field
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(-1, -1);
mv.visitEnd();
Class<?> cls = lookup().defineClass(cw.toByteArray());
cls.getMethod("m").invoke(null); // NoSuchFieldError
Приведенный выше код работает и печатает 10
, если поле имеет тип int
, но завершается неудачно, если его изменить на byte
.