Java 内部类及其原理

Java中实现内部类

Java 内部类

 

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

内部类

1.成员内部类

Java 内部类

 

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

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

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

new Main().new Inner();

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

2.局部内部类

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

Java 内部类

 

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

Java 内部类

 

3.匿名内部类

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

Java 内部类

 

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

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

4.静态内部类

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

Java 内部类

 

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

Main.Inner mi = new Main Inner();

内部类实现原理

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

定义内部类如下:

Java 内部类

 

使用javap命令进行反编译。

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

Java 内部类

 

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

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

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

编写代码如下:

Java 内部类

 

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

Java 内部类

 

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508592.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java8 Lambda表达式

概述 lambda表达式, 是Java8中的一个新特性。可以理解为一个匿名函数。 lambda表达式可以理解为将一个函数浓缩为一行代码,使代码更加简洁紧凑。 lambda表达式语法: (parameters) -> statement; 或 (parameters) -> {statements;} 参…

Java8 方法引用

概述 方法引用是用来直接访问类或实例阴茎存在的方法或者构造方法.它需要由兼容的函数式接口(lambda表达式中用到的接口)构成的目标类型上下文. 有时候, 当我们想要实现一个函数式接口的方法, 但是已经由类实现了我们想要的功能, 这时可以使用方法引用来直接使用现有的功能实现…

配置过程中的一些问题

一、 Tomcat相关问题 1、百度经验有设置用户名密码,但是按照步骤进行,到测试的时候发现还是错误的。 解决:在设置的时候应该stop Tomcat,在设置好之后再重新开启Tomcat,发现可以。 2、把web项目加入Tomcat&#xff0…

流媒体通信协议HLS与DASH的对比

简单了解 HLS(HTTP Live Streaming)协议 是由苹果公司实现的基于HTTP的流媒体通信协议,并成为Quick TIme X和IPhone软件系统的一部分。苹果的IPad也有支持HLS的能力。 HLS传出的视频文件为基于MPEG2文件的切片,每个媒体切片在服务器上单独存放。在一个流…

Activity的四种启动模式和onNewIntent()

Android中Activity启动模式详解 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。 Android总Activity的启动模式分为四种: Activity启动模式设置…

Java8 默认方法

概述 Java8新增了接口的默认方法。使用default关键字。 默认方法就是接口可以有实现方法,而且不需要实现类来实现其方法。相对于JDK1.8之前的接口来说,新增了可以接口中实现方法。 可以说在接口中实现方法一部分原因是为了lambda表达式服务的&#xf…

Android Activity 生命周期中onStart()和onResume()的区别

首先了解Activity的四种状态 Running状态:一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。 Paused状态:当Activity被另一个透明或者Dialog样式的Activity覆盖时的…

Android 原生ExoPlayer 解析

1.简述与应用范围 ExpPlayer是一个开源的,App等级的媒体API,它的开源项目包含了library和示例。 ExoPlayer相较于MediaPlayer有很多优点: 1. 支持基于http的移动流媒体协议,包括DASH,HSL,Smooth Stream。同…

Java8 Stream

概述 Java8 API中添加了一个新的抽象成为流Stream,可以以一种声明的方式处理数据。 Stream与java.io包中的InputStream和OutputStream是完全不同的概念。Java8中的Stream是对集合对象功能的增强,专注与对集合对象进行各种非常便利、高效的聚合操作&…

Java 注解原理

下面来看看Java中注解是如何实现的 创建注解类Inter: 创建测试类Test: 在程序第二句设置断点,可以看到: 可以看到,注解的实例是一个动态代理类的对象. 要想查看这个动态代理类,可以在代码中加 System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", …

myeclipse导入项目报错Target runtime Apache Tomcat v8.0 is not defined

今天想要查看一个现有的项目,本着最好使用原版本开发工具的奇怪想法,下载了一个myeclipse,在导入项目的时候报了一个错误 问题倒是挺明确的,就是项目需要的tomcat运行环境没有,有两种方法解决: 第一种方…

Android Studio查找功能(搜索功能)及快捷键

1、在当前窗口查找文本【CtrlF】 F3 向下查找关键字出现位置 ShiftF3 向上一个关键字出现位置 2、在当前工程内查找文本【CtrlShiftF】 先会弹出一个对话框,直接点击【find】,开始在整个工程内查找该字符串 查找结果如下: 3、查找类【C…

On the coexistence of transport protocols in data centers

论文信息:S. M. Irteza, A. Ahmed, S. Farrukh, B. N. Memon, and I. A. Qazi.On the coexistence of transport protocols in data centers. In Proceedings of IEEE ICC, 2014.数据中心传输协议的共存 摘要 云数据中心的出现直接导致了数据中心TCP(D…

如何做科研20171206

昨日听董大一席话,感触颇多,今日在此进行记录。(加粗字体为董大箴言) ① 关于看论文 董大问我你最近看了什么论文,我说,论文的题目没有记下来,只记得主要讲了什么。我以前一直以为一篇论文的阅…

contiki cooja仿真

最近在做contiki平台上的一些cooja仿真的东西,发现现在网上能学到的东西实在是很有限,现在在这里将我最近学到的一些东西做一下总结。 一、 关于运行的一般步骤: https://www.zhihu.com/question/48708549/answer/139050874 知乎上这个问…

6大设计原则之单一职责原则

单一职责原则 如果有一个用户管理类,类图如下 我想,任谁也能看的出这个接口设计的有问题,用户的属性和用户的行为没有分开,应该把用户的信息抽取成一个业务对象,把用户的行为抽取成一个业务对象,按照这个思路对类图进行修正,如下图所示 其实,在实际使用中我们更倾向于使用两个…

6大设计原则之里氏替换原则

面对对象中的继承 优点如下: 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性提高代码的重用性子类可以形如父类,但又异于父类提高代码的可扩展性,很多开源框架的扩展接口都是通过继承父类来实现的提高产品或项目的开放性 缺点如下: 继承是侵入性的.只要继承,就…

6大设计原则之接口隔离原则

接口隔离原则的定义 什么是接口. 实例接口,比如定义了一个Person类,然后 Person p new Pserson(); 产生一个实例,Person类就是 p 的接口类接口,就是Java中使用 interface 定义的接口 什么是隔离 隔离要求将接口尽量细化,同时接口中的方法尽量少. 接口隔离原则的实现 比如…

论文写作——origin画图

一 origin的安装 详见下面网址,内涵下载路径和破解方法。 http://www.ddooo.com/softdown/51005.htm 1. 下载origin 网址:https://thepcgo.com/origin-pro-8-0-free-download/ 2.下载破解相关压缩包 链接:https://pan.baidu.com/s/1LwA…

论文写作——texstudio+texlive

一 安装 安装见下方链接 https://jingyan.baidu.com/article/63f236287febc50208ab3deb.html 二 使用 1、选择模板 IEEE: https://ieeeauthorcenter.ieee.org/create-your-ieee-article/use-authoring-tools-and-ieee-article-templates/ieee-article-templates/ ACM:…