首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用java final关键字进行欺骗

使用java final关键字进行欺骗
EN

Stack Overflow用户
提问于 2016-04-21 09:11:33
回答 2查看 287关注 0票数 2

我正在编写一些java代码,有一次我在一件事上被阻止了。

代码语言:javascript
复制
final String action = "action1";
final Button otherAction = (findById....);
otherAction.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View v) {
            if (action.equals("action1")) {
                action = "action2";
            } else if (action.equals("action2")) {
                action = "action3";
            } else if (action.equals("action3")) {
                action = "action1";
            }
        }
    });

显然,这段代码不能工作,因为我不能为action分配一个新值,因为它是一个最终变量,因此只能初始化一次。

要从onClickListener作用域中访问一个变量,您必须声明它为final。

所以我为解决这个问题做的是:

代码语言:javascript
复制
final Button otherAction = (findById....);
otherAction.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View v) {
            if (t.action.equals("action1")) {
                t.action = "action2";
            } else if (t.action.equals("action2")) {
                t.action = "action3";
            } else if (t.action.equals("action3")) {
                t.action = "action1";
            }
        }
    });

Class t {
    public static String action = "action1";
}

我的问题是:为什么这是有效的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-21 09:37:21

字段不必是从匿名类访问的最终结果,而只是方法变量。

这是因为字段(其实体或类)一直存在,直到不再需要它(由GC决定),所以始终有一个可以分配的位置。

但是,如果要在某个地方传递匿名类实例,则当包含方法退出时,它可能仍然存在。想象一下,otherAction调用这个侦听器会在遥远的将来播下时间。但是没有任何地方可以分配这个变量了,因此它应该是最终的,并且在任何类实例化上都应该被复制。

票数 3
EN

Stack Overflow用户

发布于 2016-04-21 11:31:14

据我所知,第一个代码块不work.The“工作”这里的意思是:编译错误。

第二种方法是因为if遵循Java语言规范。对非局部参数没有限制,形式parameter..The t.action是一个静态变量.

代码语言:javascript
复制
Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.

Any local variable used but not declared in an inner class must be definitely assigned (§16) before the body of the inner class.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3

另一个注意事项是,在Java 8之前,Java 8引入了“有效终结”的概念,像上面这样用于内部类的局部变量不需要正式声明为final。有关更多细节,请访问:https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3

代码语言:javascript
复制
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.

请参阅更多关于有效期末考试的解释,请在这里:Difference between final and effectively final

关于第二个代码块工作的原因,您可以在这里阅读:Why are only final variables accessible in anonymous class?

这是我所见过的关于这个问题最合理的答案:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36764974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档