资讯专栏INFORMATION COLUMN

内部类访问局部变量的时候,为什么变量必须加上final修饰

马永翠 / 2642人阅读

摘要:局部内部类访问局部变量的机制在中,类是封装的,内部类也不例外。我们看到的内部类访问局部变量实际上只是访问了自己的成员属性而已,这和类的封装性是一致的。

这里的局部变量就是在类方法中的变量,能访问方法中变量的类当然也是局部内部类了。
我们都知道,局部变量在所处的函数执行完之后就释放了,但是内部类对象如果还有引用指向的话它是还存在的。例如下面的代码:

class Outer{                                                                       
        public static void main(String[] args){
                Outer out = new Outer();
                Object obj = out.method();
        }   
            
        Object method(){
                int locvar = 1;
                class Inner{
                        void displayLocvar(){
                                System.out.println("locvar = " + locvar);
                        }
                }
                Object in = new Inner();
                return in; 
        }
}

当out.method()方法执行结束后,局部变量 locvar 就消失了,但是在method()方法中 obj in = new Inner() 产生的 in 对象还存在引用obj,这样对象就访问了一个不存在的变量,是不允许的。这种矛盾是由局部内部类可以访问局部变量但是局部内部类对象和局部变量的生命周期不同而引起的。

局部内部类访问局部变量的机制

在java中,类是封装的,内部类也不例外。我们知道,非静态内部类能够访问外部类成员是因为它持有外部类对象的引用 Outer.this, 就像子类对像能够访问父类成员是持有父类对象引用super一样。局部内部类也和一般内部类一样,只持有了Outer.this,能够访问外部类成员,但是它又是如何访问到局部变量的呢?

实际上java是将局部变量作为参数传给了局部内部类的构造函数,而将其作为内部类的成员属性封装在了类中。我们看到的内部类访问局部变量实际上只是访问了自己的成员属性而已,这和类的封装性是一致的。那么上面的代码实际上是这样:
Object method(){
                int locvar = 1;
                class Inner{
                    private int obj;
                    public Inner(int obj){
                        this.obj = obj;
                    }
                        void displayLocvar(){
                                System.out.println("locvar = " + locvar);
                        }
                }
                Object in = new Inner(locvar);  //将locvar作为参数传给构造,以初始话成员
                return in; 
        }

那么问题又来了,我们写代码的目的是在内部类中直接控制局部变量和引用,但是java这么整我们就不高兴了,我在内部类中整半天想着是在操作外部变量,结果你给整个副本给我,我搞半天丫是整我自己的东西啊?要是java不这么整吧,由破坏了封装性--------你个局部内部类牛啊,啥都没有还能看局部变量呢。这不是java风格,肯定不能这么干。这咋整呢?
想想,类的封装性咱们一定是要遵守的,不能破坏大局啊。但又要保证两个东西是一模一样的,包括对象和普通变量,那就使用final嘛,当传递普通变量的之前我把它变成一个常量给你,当传递引用对象的时候加上final就声明了这个引用就只能指着这一个对象了。这样就保证了内外统一。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65306.html

相关文章

  • 探究final在java中作用

    摘要:关键字的字面意思是最终的不可修改的这似乎是一个看见名字就大概能知道怎么用的语法但你是否有深究过在各个场景中的具体使用方法注意事项以及背后涉及的设计思想呢一修饰变量基础修饰基本数据类型变量和引用数据类型变量相信大家都具备基本的常识被修饰的变量 final关键字的字面意思是最终的, 不可修改的. 这似乎是一个看见名字就大概能知道怎么用的语法, 但你是否有深究过final在各个场景中的具体使用方法...

    Baaaan 评论0 收藏0
  • 探究final在java中作用

    摘要:关键字的字面意思是最终的不可修改的这似乎是一个看见名字就大概能知道怎么用的语法但你是否有深究过在各个场景中的具体使用方法注意事项以及背后涉及的设计思想呢一修饰变量基础修饰基本数据类型变量和引用数据类型变量相信大家都具备基本的常识被修饰的变量 final关键字的字面意思是最终的, 不可修改的. 这似乎是一个看见名字就大概能知道怎么用的语法, 但你是否有深究过final在各个场景中的具体使用方法...

    番茄西红柿 评论0 收藏0
  • 探究final在java中作用

    摘要:关键字的字面意思是最终的不可修改的这似乎是一个看见名字就大概能知道怎么用的语法但你是否有深究过在各个场景中的具体使用方法注意事项以及背后涉及的设计思想呢一修饰变量基础修饰基本数据类型变量和引用数据类型变量相信大家都具备基本的常识被修饰的变量 final关键字的字面意思是最终的, 不可修改的. 这似乎是一个看见名字就大概能知道怎么用的语法, 但你是否有深究过final在各个场景中的具体使用方法...

    番茄西红柿 评论0 收藏0
  • 1、final 关键字 2、static 关键字 3、匿名对象 4、内部 5、包声明与访问 6、

    摘要:可以直接用接口名访问。其他类也称为外部类。汽车外部类发动机内部类内部类的分类内部类分为成员内部类与局部内部类。我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符继承与实现关系等。并且日常项目的分工也是以包作为边界。 01final关键字概念 * A: 概述 继承的出现提高了代码的复用性,并方便开发。但随之也有问题,有些类在描述完之后,不想被继承, ...

    邹立鹏 评论0 收藏0
  • java面向对象(下)

    内部类 内部类主要作用 内部类提供了更好的封装,可以吧内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。 内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问,但外部类不能访问内部类的实现细节。 匿名内部类适合用于创建那些仅需要使用一次的类。 定义内部类与外部类的语法大致相同,内部类除需要定义在其他类里面之外,还有两点区别: 内...

    awesome23 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<