Lai*_*son 3 java reflection annotation-processing
考虑一下DirectMethodHandle$Holder班级。(它是 所返回的类之一Class.forName("java.lang.invoke.DirectMethodHandle").getDeclaredClasses(),记录为返回成员类。)
以下断言在 JDK 19 下失败:
assert Class.forName("java.lang.invoke.DirectMethodHandle$Holder").isMemberClass();
Run Code Online (Sandbox Code Playgroud)
为什么?它违反了第 8.5 条的哪条规则?
和一些评论者一样,我得出的结论是,这是一个非常奇怪的错误。例如,使用某些javax.annotation.processing和某些javax.lang.model.*类,以下断言不会失败:
assert NestingKind.MEMBER == ((TypeElement)processingEnvironment.getElementUtils().getTypeElement("java.lang.invoke.DirectMethodHandle.Holder")).getNestingKind();
Run Code Online (Sandbox Code Playgroud)
因此,支持编译器的机制的输出与反射机制的输出不一致。我已经针对 JDK 提交了一个错误。
请记住,您正在查看用于 Java/JVM 交互的非常特殊的代码。查看源代码之前的注释时,您会得到提示:
\n/* Placeholder class for DirectMethodHandles generated ahead of time */\nfinal class Holder {}\nRun Code Online (Sandbox Code Playgroud)\n强调 \xe2\x80\x9cplaceholder\xe2\x80\x9d 和 \xe2\x80\x9c generated\xe2\x80\x9d
\n当我运行时jdk-17\\bin\\javap java.lang.invoke.DirectMethodHandle$Holder,我得到以下输出:
final class java.lang.invoke.DirectMethodHandle$Holder {\n static int invokeInterface(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, int);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, long);\n static long invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static void invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, double);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, int, int);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, int, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, int);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, int);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, int);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, long);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, long, long);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, java.lang.Object, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, int, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, int);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, long, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, long);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long, java.lang.Object);\n static long invokeSpecial(java.lang.Object, java.lang.Object, long);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object, long);\n static int invokeSpecial(java.lang.Object, java.lang.Object);\n static java.lang.Object invokeSpecial(java.lang.Object, java.lang.Object);\n static void invokeSpecial(java.lang.Object, java.lang.Object);\n static int invokeSpecialIFC(java.lang.Object, java.lang.Object, java.lang.Object, int);\n static int invokeSpecialIFC(java.lang.Object, java.lang.Object, int);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, double, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, double);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, int, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, int);\n static int invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, long);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static void invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, double);\n static int invokeStatic(java.lang.Object, int, int, int);\n static int invokeStatic(java.lang.Object, int, int);\n static int invokeStatic(java.lang.Object, int);\n static java.lang.Object invokeStatic(java.lang.Object, int);\n static long invokeStatic(java.lang.Object, long, int);\n static long invokeStatic(java.lang.Object, long, long);\n static long invokeStatic(java.lang.Object, long, java.lang.Object, java.lang.Object, java.lang.Object);\n static long invokeStatic(java.lang.Object, long, java.lang.Object, int, java.lang.Object);\n static long invokeStatic(java.lang.Object, long, java.lang.Object, long, java.lang.Object);\n static long invokeStatic(java.lang.Object, long, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, long);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object, long);\n static int invokeStatic(java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object, java.lang.Object);\n static java.lang.Object invokeStatic(java.lang.Object);\n static void invokeStatic(java.lang.Object);\n static java.lang.Object invokeStaticInit(java.lang.Object, java.lang.Object);\n static void invokeVirtual(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object invokeVirtual(java.lang.Object, java.lang.Object);\n static java.lang.Object newInvokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object newInvokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object newInvokeSpecial(java.lang.Object, int, int);\n static java.lang.Object newInvokeSpecial(java.lang.Object, int);\n static java.lang.Object newInvokeSpecial(java.lang.Object, java.lang.Object);\n static java.lang.Object newInvokeSpecial(java.lang.Object);\n static int getBoolean(java.lang.Object, java.lang.Object);\n static int getBooleanVolatile(java.lang.Object, java.lang.Object);\n static void putBoolean(java.lang.Object, java.lang.Object, int);\n static void putBooleanVolatile(java.lang.Object, java.lang.Object, int);\n static int getBoolean(java.lang.Object);\n static int getBooleanVolatile(java.lang.Object);\n static void putBoolean(java.lang.Object, int);\n static void putBooleanVolatile(java.lang.Object, int);\n static int getByte(java.lang.Object, java.lang.Object);\n static int getByteVolatile(java.lang.Object, java.lang.Object);\n static void putByte(java.lang.Object, java.lang.Object, int);\n static void putByteVolatile(java.lang.Object, java.lang.Object, int);\n static int getByte(java.lang.Object);\n static int getByteVolatile(java.lang.Object);\n static void putByte(java.lang.Object, int);\n static void putByteVolatile(java.lang.Object, int);\n static int getShort(java.lang.Object, java.lang.Object);\n static int getShortVolatile(java.lang.Object, java.lang.Object);\n static void putShort(java.lang.Object, java.lang.Object, int);\n static void putShortVolatile(java.lang.Object, java.lang.Object, int);\n static int getShort(java.lang.Object);\n static int getShortVolatile(java.lang.Object);\n static void putShort(java.lang.Object, int);\n static void putShortVolatile(java.lang.Object, int);\n static int getChar(java.lang.Object, java.lang.Object);\n static int getCharVolatile(java.lang.Object, java.lang.Object);\n static void putChar(java.lang.Object, java.lang.Object, int);\n static void putCharVolatile(java.lang.Object, java.lang.Object, int);\n static int getChar(java.lang.Object);\n static int getCharVolatile(java.lang.Object);\n static void putChar(java.lang.Object, int);\n static void putCharVolatile(java.lang.Object, int);\n static int getInt(java.lang.Object, java.lang.Object);\n static int getIntVolatile(java.lang.Object, java.lang.Object);\n static void putInt(java.lang.Object, java.lang.Object, int);\n static void putIntVolatile(java.lang.Object, java.lang.Object, int);\n static int getInt(java.lang.Object);\n static int getIntVolatile(java.lang.Object);\n static void putInt(java.lang.Object, int);\n static void putIntVolatile(java.lang.Object, int);\n static long getLong(java.lang.Object, java.lang.Object);\n static long getLongVolatile(java.lang.Object, java.lang.Object);\n static void putLong(java.lang.Object, java.lang.Object, long);\n static void putLongVolatile(java.lang.Object, java.lang.Object, long);\n static long getLong(java.lang.Object);\n static long getLongVolatile(java.lang.Object);\n static void putLong(java.lang.Object, long);\n static void putLongVolatile(java.lang.Object, long);\n static float getFloat(java.lang.Object, java.lang.Object);\n static float getFloatVolatile(java.lang.Object, java.lang.Object);\n static void putFloat(java.lang.Object, java.lang.Object, float);\n static void putFloatVolatile(java.lang.Object, java.lang.Object, float);\n static float getFloat(java.lang.Object);\n static float getFloatVolatile(java.lang.Object);\n static void putFloat(java.lang.Object, float);\n static void putFloatVolatile(java.lang.Object, float);\n static double getDouble(java.lang.Object, java.lang.Object);\n static double getDoubleVolatile(java.lang.Object, java.lang.Object);\n static void putDouble(java.lang.Object, java.lang.Object, double);\n static void putDoubleVolatile(java.lang.Object, java.lang.Object, double);\n static double getDouble(java.lang.Object);\n static double getDoubleVolatile(java.lang.Object);\n static void putDouble(java.lang.Object, double);\n static void putDoubleVolatile(java.lang.Object, double);\n static java.lang.Object getReference(java.lang.Object, java.lang.Object);\n static java.lang.Object getReferenceVolatile(java.lang.Object, java.lang.Object);\n static void putReference(java.lang.Object, java.lang.Object, java.lang.Object);\n static void putReferenceVolatile(java.lang.Object, java.lang.Object, java.lang.Object);\n static java.lang.Object getReference(java.lang.Object);\n static java.lang.Object getReferenceVolatile(java.lang.Object);\n static void putReference(java.lang.Object, java.lang.Object);\n static void putReferenceVolatile(java.lang.Object, java.lang.Object);\n}\nRun Code Online (Sandbox Code Playgroud)\n这是一个强烈的暗示,表明该类不是通过编译空的单行定义获得的类。看来这个实际类文件的生成器并不关心为替换类文件生成等效InnerClasses属性。由于此属性对代码的实际执行没有影响,因此\xe2\x80\x99 应该无关紧要。
因此,\xe2\x80\x99s 没有错误,无论是在编译器中还是在反射中,不匹配是由于该类并非源自源代码这一事实引起的。
\n| 归档时间: |
|
| 查看次数: |
346 次 |
| 最近记录: |