java内部类

java版本:jdk1.8

IDE:idea 18

java的内部类和普通的类本质上是一样的,但是因为所在位置的特殊,导致和普通的类在访问权限上有所区别。它的作用主要还是为了对外部隐藏,将一些临时的或者功能相同的类放到一起,便于管理。目前java的内部类包括:

1.成员内部类:定义在一个类里面。

2.局部内部类:定义在一个方法内或者一个作用域内。

3.匿名内部类:我们最常用到的一种内部类,没有类名,但是直接实现了一个接口。经常用于多线程之间的回调。

4.静态内部类:也是定义在一个类里面,但是加了static修饰。

这里面我主要说一下匿名内部类。因为它很常用,而且用好了,对于代码的维护很有帮助,可以让代码看起来很整齐,举一个例子:

这里面a这个变量,在java8之前,必须要加final修饰,java8之后新增了语法糖,不需要用final修饰了,但是并没有改变它的本质,也就是说虽然没有用final修饰,你会发现你根本改不了它:

如图,代码报错了。为什么要这样呢,这么做其实是为了保护数据的一致性。当我们使用内部类的时候,虽然我们没有给它名字和构造方法,但是编译器在编译的时候,是会帮我们生成一个的,同时,还会将a通过生成的构造方法传进去。这个时候,如果外部修改了a,那么内部类是不知道的,因为传递的不是引用,而是一个值。所以强行加上final修饰,不让你改变传进去的变量。

上面的代码,如果我们不使用匿名类写法如下:

public class RunableImpl implements Runnable {
    private  int a;
    public RunableImpl(int a)
    {
        this.a=a;
    }
    @Override
    public void run() {
        System.out.println(a);
    }
}

使用方式如下:

这段代码功能上和之前的一样,但是还是有些区别的,就是a不再需要final修饰了。原因是因为我们自己定义了一个构造方法,然后通过这个构造方法把a传进去了。这里如果该变量是引用类型,则传递的是引用,如果是值类型,则传递的是值,也就能够达到数据一致性了。

如果我们用成员内部类实现上面的代码,应该怎么写呢,参考下图:

这种写法并不需要用final修饰a,也就是说成员内部类,可以直接访问所在类里面的成员。它是怎么访问的呢,它是通过帮你生成一个构造方法,这个构造方法会将当前所在的类传递进来,自然也就可以访问了。

继续改造,使用局部内部类来实现:

这个时候a就需要final修饰了,不然编译不通过:

这里说明系统帮你生成的构造方法,传递的是a的值,而并非引用。所以如果你不想让a用final修饰,那么你可以自己写一个构造方法,然后把a传进来,如下:

到这里,我们可以发现,所谓内部类和普通类,其实是一样的,只是因为编译器帮我们做了一部分工作,所以看起来和普通的类有些不一样,但是编译后的代码,和普通的类就没有区别了。这就像aop里面的静态织入一样,看起来的代码和最终编译出来的代码会因为aop的织入导致有所差别。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值