Java 内部类及其原理
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 内部类及其原理的更多相关文章
- 夯实Java基础系列18:深入理解Java内部类及其实现原理
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- Java内部类的使用小结
转载:http://android.blog.51cto.com/268543/384844/ Java内部类的使用小结 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可 ...
- (转载)Java内部类的使用小结
原文摘自:http://android.blog.51cto.com/268543/384844/ 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态stati ...
- 深入理解Java内部类
内部类就是定义在一个类中的另外一个类,是一种从属关系.在没有实际了解内部类之前,我始终困惑,为什么要在一个类中定义另外一个类,这不是增加代码结构复杂度么?现在才大致能知道这种设计的优势是大于 ...
- Java内部类与外部类
错误提示: 没有任何类型 TestThread 的外层实例可访问.必须用类型 TestThread 的外层实例(例如,x.new A(),其中 x 是 TestThread 的实例)来限定分配. pu ...
- 我的Java开发学习之旅------>在Dos环境下Java内部类的编译和运行
习惯了在IDE工具上进行代码编写,连最基本的Javac命令和Java命令都忘记的差不多了,今天对一个Java内部类进行编译和运行的时候,就出糗了.IDE是把双刃剑,它可以什么都帮你做了,你只要敲几行代 ...
- JAVA 内部类 (一)
可将一个类定义置入另一个类定义中.这就叫作“内部类”.内部类对我们非常有用,因为利用它可对那些逻辑上相互联系的类进行分组,并可控制一个类在另一个类里的“可见性”.然而,我们必须认识到内部类与以前讲述的 ...
- Java内部类的基本解析
内部类 内部类的基本概念 所谓的内部类也就是在一个类的内部进行其他类结构的嵌套操作. 为什么要使用内部类? 这就要引用一句十分著名的一本书叫<Think in java>中的一句名言了—— ...
- Java内部类的使用小结 形参为什么要用final
部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类即类名和文 ...
随机推荐
- 从 Spring Cloud 看一个微服务框架的「五脏六腑」
原文:https://webfe.kujiale.com/spring-could-heart/ Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构 ...
- eclipse使用和快捷键
一.快捷键 - ctrl + shift + o 导包 - ctrl + shift + t 快速查找某个类 - 先按ctrl + 2 ,再点L, 创建变量并命名 - ctrl + o , 在当前类中 ...
- UC手机浏览器js加入收藏夹
概述 对于某些网站来说,让用户一键把网页加入收藏夹的设计是非常棒的,它能提醒用户把网页加入收藏夹,从而增加用户的回访率,使网站获得更多的流量. 在PC端,只有ie和ff支持用js把网页加入收藏夹的操作 ...
- SpringBoot中集成redis
转载:https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html 不是使用注解而是代码调用 需要在springbo ...
- Scala - 快速学习01 - Scala简介
Scala简介 Scala(Scalable Language)是一门多范式(multi-paradigm)编程语言,Scala的设计吸收借鉴了许多种编程语言的思想,具备面向对象编程.函数式编程等特性 ...
- 1.Git起步-Git的三种状态以及三种工作区域、CVCS与DVCS的区别、Git基本工作流程
1.Git基础 版本控制系统是一种用于记录一个或多个文件内容变化,以便将来查阅恢复特定版本修订情况的系统. Git是一种分布式版本控制系统(Distributed Version Control Sy ...
- 【ABP框架系列学习】介绍篇(1)
0.引言 该系列博文主要在[官方文档]及[tkbSimplest]ABP框架理论研究系列博文的基础上进行总结的,或许大家会质问,别人都已经翻译过了,这不是多此一举吗?原因如下: 1.[tkbSim ...
- 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装爬虫框架Scrapy(离线方式和在线方式)(图文详解)
不多说,直接上干货! 参考博客 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装OpenCV(离线方式和在线方式)(图文详解) 第一步:首先,提示升级下pip 第二步 ...
- npm无响应处理办法
方法一:使用cnpm 1. 安装 `npm install cnpm -g` 2.设置使用淘宝镜像源 `npm install cnpm -g --registry=https://registry. ...
- Number(),parseInt(),parseFloat(),Math.round(),Math.floor(),Math.ceil()对比横评
首先,这些处理方法可分为三类. 1,只用来处理数字取整问题的:Math.round(),Math.floor(),Math.ceil(): 2,专门用于把字符串转化成数值:parseInt(),par ...