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,一经查实,立即删除!

相关文章

西游日记7/27

已经到第四天了,觉得需要写一些进展来督促一下自己。 早上8点钟左右到的实验室,将昨天没有回顾完的论文再次回顾一遍,又重新发现了一些点,确实,在完全明白之前,一篇好的论文是常读常新的。在吃午饭之前&am…

JVM 垃圾回收机制

首先JVM的内存结构包括五大区域: 程序计数器、虚拟机栈、本地方法栈、方法区、堆区。其中程序计数器、虚拟机栈和本地方法栈3个区域随线程启动与销毁, 因此这几个区域的内存分配和回收都具有确定性,不需要过多考虑回收的问题。而Java堆区和方法区则不一样…

Modeling and Analyzing the Influence of Chunk Size Variation on Bitrate Adaptation in DASH 名字解释0728

在看“Modeling and Analyzing the Influence of Chunk Size Variation on Bitrate Adaptation in DASH”的时候遇到挺多的名词不是很明白,在这里做一下学习笔记(按照论文顺序)。 1、CDN server:“CDN将源站内容分发至最接近用户的…

Java8 Lambda表达式

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

西游日记0728

今天要早点翘班儿,请表妹儿吃饭,现在来总结一下我今天的干活吧。 早上8点钟到的实验室,私以为还可以提早一点,确实是一个人的时候比较容易狂欢,早上的工作效率有点低啊。早上嘛,就是看论文诺,看…

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文件的切片,每个媒体切片在服务器上单独存放。在一个流…

Java8 Optional类

概述 到目前为止,著名的NullPointerException是导致Java应用程序失败的最常见原因。过去,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写…

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运行环境没有,有两种方法解决: 第一种方…

ExoPlayer用户手册

贴上原网址:https://google.github.io/ExoPlayer/guide.html 非完全翻译,有需要可以原网址自取,我发现网上也蛮多这个指导的翻译,可以去看看~ 开始啦!: ExoPlayer是一个开源的应用级媒体播放器&#xff0…

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

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

ZJU夏令营面试记录

首先记录一下这次夏令营面试。 1、进去后,圆桌会议,8个老师坐着。准备了6份简历简历表示不够,以后要多打几份。 2、首先,用英语介绍一下自己的专业(表示一脸懵逼) 3、说一下你这个暑假做了什么东西&…

Python的闭包

什么是闭包 #定义一个函数 def test(number): #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包 def test_in(number_in): print("in test_in 函数, number_in is %d"%number_in) ret…