ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

带有注释参数的私有方法的Android java.lang.VerifyError

2019-12-10 02:00:18  阅读:284  来源: 互联网

标签:annotations verifyerror java android


我有一个非常简单的项目可以编译,但是无法在Emulator上启动.问题在于这种方法:

private void bar(@Some String a) {} // java.lang.VerifyError

如果删除注释,可以避免该问题

private void bar(String a) {} // OK

或方法可见性已更改:

void bar(@Some String a) {} // OK
public void bar(@Some String a) {} // OK
protected void bar(@Some String a) {} // OK

知道原始方法有什么问题吗?这是达尔维克虫吗?

如果有人想尝试代码,这里是:

Test.java:

public class Test {

    private void bar(@Some String a) {}

    public void foo() {
        bar(null);
    }
}

Some.java:

public @interface Some {}

MainActivity.java:

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        new Test().foo();
    }
}

堆栈跟踪:

ERROR/dalvikvm(1358): Could not find method com.my.Test.bar, referenced from method com.my.Test.foo
WARN/dalvikvm(1358): VFY: unable to resolve direct method 11: Lcom/my/Test;.bar (Ljava/lang/String;)V
WARN/dalvikvm(1358): VFY:  rejecting opcode 0x70 at 0x0001
WARN/dalvikvm(1358): VFY:  rejected Lcom/my/Test;.foo ()V
WARN/dalvikvm(1358): Verifier rejected class Lcom/my/Test;
DEBUG/AndroidRuntime(1358): Shutting down VM
WARN/dalvikvm(1358): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
ERROR/AndroidRuntime(1358): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(1358): java.lang.VerifyError: com.my.Test
ERROR/AndroidRuntime(1358):     at com.my.MainActivity.onCreate(MainActivity.java:13)
ERROR/AndroidRuntime(1358):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
ERROR/AndroidRuntime(1358):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
ERROR/AndroidRuntime(1358):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
ERROR/AndroidRuntime(1358):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
ERROR/AndroidRuntime(1358):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
ERROR/AndroidRuntime(1358):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(1358):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(1358):     at android.app.ActivityThread.main(ActivityThread.java:3948)
ERROR/AndroidRuntime(1358):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(1358):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(1358):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
ERROR/AndroidRuntime(1358):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
ERROR/AndroidRuntime(1358):     at dalvik.system.NativeStart.main(Native Method)

解决方法:

这实际上是Eclipse 3.5编译器(Bug 289576)的一个错误,该错误使用带注释的参数更改了方法的private修饰符,从而使该方法成为“ package-private”.因此,您的:

private void bar(@Some String a) {…}

.class文件中的内容变为:

void bar(@Some String a) {…}

但是,更改后的方法仍由invokespecial JVM指令调用,该指令仅用于私有方法调用(也用于某些其他非方法方面的东西),但是令人惊讶的是,它也适用于Sun / Oracle JVM上的“程序包私有”方法.
在Android期间.class => .dex转换invokespecial JVM指令被转换为直接调用Dalvik指令,该指令只能调用私有方法和构造函数.由于bar()方法已成为程序包可见的方法,invoke-direct找不到它,并引发NoSuchMethodError.

解决方案是使用Eclipse 3.6或javac编译器(通过build.xml ant脚本).

标签:annotations,verifyerror,java,android
来源: https://codeday.me/bug/20191210/2098518.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有