加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么阴影会影响`final`行为?

发布时间:2020-12-15 04:25:30 所属栏目:Java 来源:网络整理
导读:这里有三个SSCCE,我认为应该编译和行为相同.我唯一要改变的是第一行“跑”. 图表1 public class FinalExperiment { private TinyThing thing; public static void main(String[] args) { FinalExperiment instance = new FinalExperiment(); instance.run();
这里有三个SSCCE,我认为应该编译和行为相同.我唯一要改变的是第一行“跑”.

图表1

public class FinalExperiment {
    private TinyThing thing;

    public static void main(String[] args) {
        FinalExperiment instance = new FinalExperiment();
        instance.run();
    }

    public void run() {
        final TinyThing thing = new TinyThing();
        System.out.println("Got a thing here: " + thing);
    }

    private static class TinyThing {
        public TinyThing() {}
        public String toString() { return "Hello!"; }
    }
}

这有效;它成功编译,并打印:“有一件事:你好!”

图表2

public class FinalExperiment {
    private TinyThing thing;

    public static void main(String[] args) {
        FinalExperiment instance = new FinalExperiment();
        instance.run();
    }

    public void run() {
        final TinyThing otherThing = thing;
        System.out.println("Got a thing here: " + otherThing);
    }

    private static class TinyThing {
        public TinyThing() {}
        public String toString() { return "Hello!"; }
    }
}

这有效;它编译成功,并打印:“有一个东西在这里:null”

图表3

public class FinalExperiment {
    private TinyThing thing;

    public static void main(String[] args) {
        FinalExperiment instance = new FinalExperiment();
        instance.run();
    }

    public void run() {
        final TinyThing thing = thing;
        System.out.println("Got a thing here: " + thing);
    }

    private static class TinyThing {
        public TinyThing() {}
        public String toString() { return "Hello!"; }
    }
}

无法使用此消息进行编译:

FinalExperiment.java:10: error: variable thing might not have been initialized
            final TinyThing thing = thing;
                                    ^
1 error

为什么?图2和图3之间的唯一区别在于我在运行方法中隐藏了一些东西.编译器似乎不应该更简单地关注,因为正在发生阴影.

解决方法

是的,在图3中发生了阴影,但实际上您正在尝试声明一个最终变量,然后将其分配给自己.

final TinyThing thing = thing;  // Assign to self!

尚未为其分配值,因此您会收到未初始化的编译器错误.无论局部变量是否是最终的,都会发生这种情况.

要引用实例变量,请使用此限定条件.

final TinyThing thing = this.thing;  // Bypass shadowing.

这将编译并导致与图表2相同的输出:

Got a thing here: null

此示例无法以相同方式编译,例如:

public class SelfDefineExample {
    public static void main(String[] args) {
        int i = i;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读