java - 局部内部类能访问非final修饰的局部变量;

查看:201
本文介绍了java - 局部内部类能访问非final修饰的局部变量;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

问题

局部内部类是不能访问非final修饰的局部变量的,但是我测试的时候居然可以

代码如下

package com.lafeier1;
public class Outer{//外部类Outer
    void show(){
        int num =10;//局部变量num
        //局部内部类Inner
        class Inner{
            void dosomething(){
                System.out.println(num);//局部内部类也能访问非final修饰的局部变量吗?
            }
        }
        new Inner().dosomething();
    }

    public static void main(String[] args) {
        new Outer().show();

    }

}

解决方案

基本同意 @小小码农努力学习 ,但其实并不能说是去掉了限制,可以说这是一颗语法糖语法糖而已,因为对于 JVM 而言,并没有内部类和外部类的概念,只是两个字节码文件 Outer.classOuter$Inner.class

还原一下语法糖的内幕:

public class Outer{//外部类Outer
    void show(){
        final int num =10;//局部变量num
        //局部内部类Inner
        class Inner{
            private final int val$num;
            private final Outer this$0;
            public Inner(Outer outer,int num){
                val$num = num;
                this$0 = outer;
            }
            void dosomething(){
                System.out.println(num);//局部内部类也能访问非final修饰的局部变量吗?
            }
        }
        new Inner(this,num).dosomething();
    }
}

看懂上面的代码就知道为什么我们可以访问外部类的成员变量方法体的局部变量(当然私有成员还需要在外部类添加相应的类似 get() 方法的语法糖,这里不探讨。)因为方法体的局部变量在内部类中会拷贝成内部类的成员变量,即并不是同一个内存区域(废话,局部变量是在栈中分配的,而类的成员变量是在堆中分配的),为了保持两者一致性,就只能限制他们初始化之后不能修改。

至于 JDK 1.8 加的语法糖就更简单了,就是自动加了一下 final,所以下面的代码还是编译不通过的。

public class Outer{//外部类Outer
    void show(){
        int num =10;//局部变量num
        //局部内部类Inner
        class Inner{
            void dosomething(){
                System.out.println(num);//局部内部类也能访问非final修饰的局部变量吗?
            }
        }
        num = 11;
        new Inner().dosomething();
    }
}

这篇关于java - 局部内部类能访问非final修饰的局部变量;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆