在检查 JVM 源代码后想通了。
The error (Incompatible object argument for function call) means that the object on which the invocation is performed doesn't match the expected (by method signature) type (I assumed it had something to do with object arguments, but you get a slightly different error in that case).
Apparently, javassist doesn't insert proper instructions when you assign an object to an object of another class (alternatively it can fail the statement).
Javassist will take the following code as valid:
Object x ...;
String s = x; // javac requires cast here, javassist doesn't
s.isEmpty();
normally compiles into:
1 aload_1 // push x on stack
2 checkcast java/lang/String // check we can fit x into s
3 astore 2 // s = x;
4 aload 2 // 'this' for isEmpty()
5 invokevirtual String.isEmpty() // stack top used as 'this'
javassist (at least the version that I have) just doesn't add checkcast instruction, and the VM has no guarantee that at the time invokevirtual is called the stack top contains String, which is required because the invokvirtual is invoking a method from String class.
Remedy would be:
- use explicit cast in assignments
- fix javassist
- use local variables of explicit type