其他分享
首页 > 其他分享> > 为什么编译器在内部类中接受非最终变量?

为什么编译器在内部类中接受非最终变量?

作者:互联网

我正在使用seekbar创建MediaPlayer.在这里,mp是MediaPlayer对象,而seeker是在MainActivity类中创建的seekbar对象.

我的理解是匿名内部类只能访问最终成员,然后可运行对象如何访问这些对象(mp和seeker).

     h = new Handler();  // create a handler for the MainActivity

 //create a runnable activity to change the progress of seekbar in MainThread for every 1 sec
   Runnable r = new Runnable() {
        @Override
        public void run() {
            if (mp != null) {
                seeker.setProgress(mp.getCurrentPosition() / 1000);
            }
           h.postDelayed(this, 1000);
        }
   };

    this.runOnUiThread(r);

注意:该代码可以正常工作.感谢帮助.

解决方法:

它发生了,因为有一个有效的终结.

jls-8.1.3:

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

jls-4.12.4:

If a variable is effectively final, adding the final modifier to its declaration will not introduce any compile-time errors. Conversely, a local variable or parameter that is declared final in a valid program becomes effectively final if the final modifier is removed.

当变量仅设置一次并且在内部类中使用时,编译器会将变量的修饰符转到final.

考虑以下代码Tests.java:

public class Tests  {
   public static void main(String[] args) throws Throwable {
       String value = "Hello";

       Runnable runnable = new Runnable() {
           @Override
           public void run() {
               System.out.println(value);
           }
       };
   }
}

上面的代码在编译时将产生以下代码.您能看到编译器将value的修饰符更改为final吗?

Tests.class(已解码):

public class Tests {
    public Tests() {
    }

    public static void main(String[] args) throws Throwable {
        final String value = "Hello";
        Runnable var10000 = new Runnable() {
            public void run() {
                System.out.println(value);
            }
        };
    }
}

但是,如果您更改变量的值(请参见下面的代码),它将不会被编译,因为编译器知道它不是有效的最终变量:

public class Tests  {
   public static void main(String[] args) throws Throwable {
       String value = "Hello";
       value = "world";

       Runnable runnable = new Runnable() {
           @Override
           public void run() {
               System.out.println(value);
           }
       };
   }
}

标签:compiler-errors,java,android
来源: https://codeday.me/bug/20191026/1937479.html