Java中final的进一步理解

Java中final的进一步理解

final修饰符的作用

在JMM中要求final域(属性)的初始化动作必须在构造方法return之前完成。换言之,一个对象创建以及将其赋值给一个引用是两个动作,对象创建还需要经历分配空间和属性初始化的过程,普通的属性初始化允许发生在构造方法return之后(指令重排序)。

普通变量和final变量到底又有什么区别呢?看看下面这段代码的输出结果

public class FinalConstructorTest {

    static abstract class A {
        public A() {
            display();
        }

        public abstract void display();
    }

    static class B extends A {
        private int INT = 100;
        private final int FINAL_INT = 100;
        private final Integer FINAL_INTEGER = 100;
        private String STR1 = "abc";
        private final String FINAL_STR1 = "abc";
        private final String FINAL_STR2 = new String("abc");
        private final List<String> FINAL_LIST = new ArrayList<>();

        private B(){
            super();
            System.out.println("abc");
        }

        public void display() {
            System.out.println(INT);
            System.out.println(FINAL_INT);
            System.out.println(FINAL_INTEGER);
            System.out.println(STR1);
            System.out.println(FINAL_STR1);
            System.out.println(FINAL_STR2);
            System.out.println(FINAL_LIST);
        }
    }

    public static void main(String[] args) {
        new B();
    }
}   

输出结果如下:
0
100
null
null
abc
null
null
abc

匿名内部类使用外部变量,这个变量必须用final来声明才可以被使用

伪代码如下:

public void test() {
    final int a = 100;
    new A() {
        public void display() {
            System.out.println(a);
        }   
    }
    其他操作
}

这其实是对一个语法的疑问,本身没什么好解释的,但如果非要解释,可以从这个角度来理解:在编译时,这个地方会自动生成一个匿名内部类,而本地变量a的作用域是在方法test()中,它如何能用到另一个内部类中呢?

其中一种方式是参数传递,另一种方式就是作为一个属性存在于匿名内部类对象中。无论哪一种方式都会在匿名内部类对象中有一份数据拷贝。

JVM在设计时并不知道我们的代码会怎么写,或者说不明确在所创建的匿名内部类中到底会做什么,例如在代码中完全可以在内部创建一个线程来使用这个变量,或者创建一个任务提交给线程池来使用这个变量。如果是这样,匿名内部类的运行与该方法本身的运行处于两个线程中,当外部方法可能已经结束时,那么相应的局部变量的作用域已经结束,自动会被回收,要保证匿名内部类一直可以使用该变量,就只能用拷贝的方法。

如果这个属性不是final修饰的,在匿名内部类中使用“同名”的变量操作,并且可以对它做任意修改,自然外部也应当能感知到。但是事实上不能感知到,因为这是一份数据拷贝。这种语法的设计手段是为了避免误解,语法上强制约束它为final修饰符。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值