这两天测试了一段代码,在 Java11 上正常运行,在 android 上运行报 NoSuchMethodError 异常,异常处就一句
//buf 是一个 ByteBuffer
buf.flip()
报的异常是
java.lang.NoSuchMethodError: No virtual method flip()Ljava.nio.ByteBuffer in class java.nio.ByteBuffer (我凭记忆还原的,可能不完全一样)
通常出现这样的问题的时候我第一反应是使用了 android 不支持的高版本 API 导致的。但翻了下 Java 的 API 文档,发现 flip 函数在有 ByteBuffer 的时候就存在了,然后再看方法签名,注意到报异常的函数签名是 flip()Ljava.nio.ByteBuffer,但查阅的文档中这个函数的签名应该是 flip():Ljava.nio.Buffer,猜测是不是编译的时候选择调用了另一个高版本中存在的方法签名,但是不知道怎么处理。
后来在 StackOverflow 上找到了这个问题的解答。在 Java9 的时候 ByteBuffer 覆写了父类 Buffer 的 flip,mark,reset 等函数,并将返回值改为了 ByteBuffer,导致高版本编译的时候,javac 选择调用了 flip()Ljava.nio.ByteBuffer,在低版本的运行环境中没有这个方法签名,导致出错。解决方法是((Buffer)buf).flip()
感觉 Java 在这块的设计有些奇特,Java 没有返回值重载,但 JVM 实现上却会将不同返回值认定为不同的方法。
//buf 是一个 ByteBuffer
buf.flip()
报的异常是
java.lang.NoSuchMethodError: No virtual method flip()Ljava.nio.ByteBuffer in class java.nio.ByteBuffer (我凭记忆还原的,可能不完全一样)
通常出现这样的问题的时候我第一反应是使用了 android 不支持的高版本 API 导致的。但翻了下 Java 的 API 文档,发现 flip 函数在有 ByteBuffer 的时候就存在了,然后再看方法签名,注意到报异常的函数签名是 flip()Ljava.nio.ByteBuffer,但查阅的文档中这个函数的签名应该是 flip():Ljava.nio.Buffer,猜测是不是编译的时候选择调用了另一个高版本中存在的方法签名,但是不知道怎么处理。
后来在 StackOverflow 上找到了这个问题的解答。在 Java9 的时候 ByteBuffer 覆写了父类 Buffer 的 flip,mark,reset 等函数,并将返回值改为了 ByteBuffer,导致高版本编译的时候,javac 选择调用了 flip()Ljava.nio.ByteBuffer,在低版本的运行环境中没有这个方法签名,导致出错。解决方法是((Buffer)buf).flip()
感觉 Java 在这块的设计有些奇特,Java 没有返回值重载,但 JVM 实现上却会将不同返回值认定为不同的方法。