Java中实现内部类

内部类相信大家都用过很多次了,就不说它是怎么用的了。

内部类

1.成员内部类

需要注意的是, 当成员内部类拥有和外部类同名的成员变量或这方法时, 默认情况下访问的是内部类的成员, 如要访问外部类的同名成员, 需要使用以下形式:

外部类.this.成员变量
外部类.this.成员方法

内部类是依附外部类而存在的, 也就是说要创建成员内部类的对象,前提是创建一个外部类的对象,创建成员内部类的方式如下:

new Main().new Inner();

成员内部类可以拥有private访问权限、protected访问权限、public访问权限、默认访问权限。如用private修饰,则只能在外部类的内部访问。

2.局部内部类

局部内部类是定义在一个方法或作用域中的类,它的访问权限仅限于方法内或作用域内。

局部内部类也可以返回,像这样:

3.匿名内部类

匿名内部类应该是我们平常使用最多的了,如下面创建线程:

匿名内部类在编译的时候有系统自动起名:Main$1

匿名内部类是没有构造器的类,大部分用于继承其他类或实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写

4.静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类前加上了static。静态内部类是不需要依赖于外部类的,与静态成员变量类似。

外部创建该静态类时可以如下创建:

Main.Inner mi = new Main Inner();

内部类实现原理

内部类为什么能够访问外部类的成员?

定义内部类如下:

使用javap命令进行反编译。

编译后得到Main.class Main$Inner.class两个文件,反编译Main$Inner.class文件如下:

可以看到,内部类其实拥有外部类的一个引用,在构造函数中将外部类的引用传递进来。

匿名内部类为什么只能访问局部的final变量?

其实可以这样想,当方法执行完毕后,局部变量的生命周期就结束了,而局部内部类对象的生命周期可能还没有结束,那么在局部内部类中访问局部变量就不可能了,所以将局部变量改为final,改变其生命周期。

编写代码如下:

这段代码编译为Main.class Main$1.class两个文件,反编译Main$1.class文件如下:

可以看到,java将编译时已经确定的值直接复制,进行替换,将无法确定的值放到了内部类的常量池中,并在构造函数中将其从常量池取出到字段中。

可以看出,java将局部变量m直接进行复制,所以其并不是原来的值,若在内部类中将m更改,局部变量的m值不会变,就会出现数据不一致,所以java就将其限制为final,使其不能进行更改,这样数据不一致的问题就解决了。

匿名内部类为什么访问外部类成员字段不用final?

上面说了,final关键字是为了解决数据不一致的问题,因为内部类中存有外部类的引用,所有对外部类中字段的修改都会真实的反映到外部类实例本身,所以不需要用final来修饰。

Java 内部类及其原理的更多相关文章

  1. 夯实Java基础系列18:深入理解Java内部类及其实现原理

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  2. Java内部类的使用小结

    转载:http://android.blog.51cto.com/268543/384844/ Java内部类的使用小结 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可 ...

  3. (转载)Java内部类的使用小结

    原文摘自:http://android.blog.51cto.com/268543/384844/   内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态stati ...

  4. 深入理解Java内部类

         内部类就是定义在一个类中的另外一个类,是一种从属关系.在没有实际了解内部类之前,我始终困惑,为什么要在一个类中定义另外一个类,这不是增加代码结构复杂度么?现在才大致能知道这种设计的优势是大于 ...

  5. Java内部类与外部类

    错误提示: 没有任何类型 TestThread 的外层实例可访问.必须用类型 TestThread 的外层实例(例如,x.new A(),其中 x 是 TestThread 的实例)来限定分配. pu ...

  6. 我的Java开发学习之旅------>在Dos环境下Java内部类的编译和运行

    习惯了在IDE工具上进行代码编写,连最基本的Javac命令和Java命令都忘记的差不多了,今天对一个Java内部类进行编译和运行的时候,就出糗了.IDE是把双刃剑,它可以什么都帮你做了,你只要敲几行代 ...

  7. JAVA 内部类 (一)

    可将一个类定义置入另一个类定义中.这就叫作“内部类”.内部类对我们非常有用,因为利用它可对那些逻辑上相互联系的类进行分组,并可控制一个类在另一个类里的“可见性”.然而,我们必须认识到内部类与以前讲述的 ...

  8. Java内部类的基本解析

    内部类 内部类的基本概念 所谓的内部类也就是在一个类的内部进行其他类结构的嵌套操作. 为什么要使用内部类? 这就要引用一句十分著名的一本书叫<Think in java>中的一句名言了—— ...

  9. Java内部类的使用小结 形参为什么要用final

    部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类即类名和文 ...

随机推荐

  1. metools,个人工具站点分享

    需要[加密/解密][编码/解码][生成二维码]的时候不用再进百度点广告~ 也不需要去收藏夹找网址~ 我的目的大概就是如此. 项目地址:https://github.com/yimogit/metool ...

  2. Hadoop 多表关联

    一.实例描述 多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息.下面进入这个实例. 输入是两个文件,一个代表工厂表,包含工厂名列和地址编号列:另一个代表地址列,包含地 ...

  3. 第83节:Java中的学生管理系统分页功能

    第83节:Java中的学生管理系统分页功能 分页功能一般可以做成两种,一种是物理分页,另一种是逻辑分页.这两种功能是有各自的特点的,物理分页是查询的时候,对数据库进行访问,只是查一页数据就进行返回,其 ...

  4. Python的简单介绍

    0. 前言 最近在从头梳理Python的相关知识,有助于以后更好地学习新知识.这篇博客,我简单介绍一下Python语言的有关内容. 1. Python介绍 Python的创始人为荷兰人吉多·范罗苏姆( ...

  5. 封装手风琴!使用jQuery!

    //封装手风琴 /** * * * */ $.fn.accordion = function (colors, width) { var width=width||0; var colors= col ...

  6. 【app】自动化环境搭建(Appium)for java

    Appium来做app自动化相信大家都很熟悉了吧,就不再赘述他的概念和作用了,我们接下来着重介绍怎么来搭建整个app自动化环境,整个环境包括如下几个步骤: 1.安装jdk和eclipse及配置jdk的 ...

  7. 一款好用 mongodb 可视化工具

    最近想自己搭建一个个人博客,所以学了下mongodb,mongodb是用命令行输入的,有些人可能不太习惯,我自己找了下mongodb的一些可视化工具,一开始安装的是mongoVUE,mongoVUE页 ...

  8. python之找最后一个人

    题目大概是:有10个人围成一圈,从第一个人数,数到3的人出局,问最后一个人是谁? 围成一圈,那就是无限循环,直至最后一个人,我们可以把10个人看做一个列表,每循环一次就把除3为0的数去除,下次再次循环 ...

  9. mysql 开发进阶篇系列 10 锁问题 (相同索引键值或同一行或间隙锁的冲突)

    1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...

  10. app 压力测试

    monkey工具详解 https://blog.csdn.net/jffhy2017/article/details/54572400 ----------------------- Android ...