java – 最终字段和匿名类
关于匿名课和最终字段的解释我仍然不满意.有很多问题试图解释明显的问题,但我没有找到所有问题的答案:-)
假设以下代码: public void method(final int i,int j) { final int z = 6; final int x = j; int k = 5; new Runnable() { public void run() { System.out.print(i); System.out.print(x); System.out.print(z); System.out.print(k); } }; } >由于“不完整”的k属性,无法编译此代码. 当我搜索解决方案时,我和x的确切可行,我发现这个answer说:
如果它们是方法的参数,它如何适用于字段i和x?在编译期间不知道它们?这种方法适用于z. 另一方面,有关于stack issues的解释:
我会理解匿名类在创建过程中以某种方式复制了所有必需的内容(字段).缺少final有明显的问题,如果匿名类声明下面的某些代码会改变值,则执行使用可能的陈旧值. 但是,这可以解决当匿名类’方法在使用的属性范围之外执行时的问题. 但这种方法即使没有最终声明也应该有效,因为它只复制所有字段. 这两种方法对我来说都是独立的.说到哪 – 它可以解决我的问题 – 我还没有找到工作最终方法领域.即使方法完成,它们也不会从堆栈中删除?对我来说似乎是胡说八道,但它会解释很多事情:-) 什么是正确的答案? 解决方法
在我看来,你在被宣告为final的变量和它是一个常量之间感到困惑.
编译器不会用常量替换对局部变量的所有引用 – 但是当构造匿名类的实例时,每个相关变量的当前值将传递给构造函数,并存储在匿名类中的变量中.这对于参数和任何其他类型的局部变量一样好. 所以这段代码: public static void method(final int x) { Runnable r = new Runnable() { @Override public void run() { System.out.println(x); } }; r.run(); } 大致相当于: public static void method(final int x) { Runnable r = new AnonymousRunnable(x); r.run(); } private static class AnonymousRunnable implements Runnable { private final int x; AnonymousRunnable(int x) { this.x = x; } @Override public void run() { System.out.println(x); } } 我已经将方法和嵌套类都设置为静态,以避免担心这是否被捕获. 当捕获局部变量时必须是最终的,以避免可能引起混淆的情况.假设情况并非如此 – 请考虑以下示例: void method() { int x = 10; Runnable r = new Runnable() { @Override public void run() { System.out.println(x); } }; x = 20; r.run(); // Should this print 10 or 20? } 使用匿名类的当前工作方式,但只删除最终限制,它将打印10 …但开发人员可能希望它打印20.同样,您应该考虑如果在run方法中修改x会发生什么. (如Joop的回答所述,在Java 8中,捕获的局部变量是“有效的最终” – 所以它们表现得好像你已经宣布它们是最终的,但没有明确地这样做.) 作为一种不同方法的示例,C#以不同的方式处理闭包(对于匿名函数),将局部变量提升为一种匿名类,以便可以对它们进行修改.这是一种更复杂的方法,但更灵活一点.您可能会发现我的article about closures in Java and C#很有用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |