首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么带有内部类的Java代码会生成第三个SomeClass $ 1.class文件?

这个问题涉及到Java编译器在编译带有内部类的Java代码时生成的文件。

在Java中,内部类是一个类的成员,它可以访问外部类的所有成员。当Java编译器编译带有内部类的Java代码时,它会生成多个.class文件。其中,一个.class文件对应于外部类,另一个.class文件对应于内部类。

在这个例子中,SomeClass是一个外部类,而$1是一个内部类。编译器生成了两个.class文件,分别是SomeClass.class和SomeClass$1.class。其中,SomeClass.class对应于外部类SomeClass,而SomeClass$1.class对应于内部类$1。

这种生成多个.class文件的机制使得Java可以更好地支持封装和模块化。内部类可以访问外部类的所有成员,而外部类的成员对内部类是私有的。这种机制可以帮助开发人员更好地组织和管理代码。

总之,当Java编译器编译带有内部类的Java代码时,它会生成多个.class文件,其中一个.class文件对应于外部类,另一个.class文件对应于内部类。这种机制有助于更好地组织和管理代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

死磕Java部类(一篇就够)

为什么需要内部类为什么部类(包括匿名内部类、局部内部类),持有外部类引用? 为什么匿名内部类使用到外部类方法中局部变量时需要是final类型? 如何创建内部类实例,如何继承内部类?...为什么部类(包括匿名内部类、局部内部类),持有外部类引用? 问这个问题,显得我是个杠精,您先别着急,其实我想问是,内部类Java是怎么实现。...Demo.java,在Demo类同目录下可以看到生成了二个class文件 ?...public void run() { } }; } 同样执行javac Demo.java,这次多生成了一个Demo$1.class,反编译查看代码 package...方法局部内部类,我这里就不赘述了,原理都是一样,大家可以自行试验。 这样我们算是解答了第二个问题,来看第三个问题。 为什么匿名内部类使用到外部类方法中局部变量时需要是final类型

95930

匿名内部类何为匿名?

学过Java同学肯定听说过匿名内部类, 不过不知道有没有仔细深究过它, 比如为什么称之为匿名? 为什么也算是一个类,而且是内部类? 它和内部类有什么区别?...匿名内部类 先来看一段匿名内部类代码, 这里需要先定义一个抽象类, abstract class Person { public abstract void doSomething(); }..., 匿名内部类省去了实现一个 Person具体类步骤, 比如说上面的代码可以用这样非匿名内部类来实现, public class Student extends Person { public...虽然代码上看起来少了这个类,但其实在字节码中,还是有生成一个类, 比如上面的代码 Demo类,在编译后会生成两个文件, Demo.class Demo$1.class 可以用 javap -c Demo...类, 虽然我们没有继承 Person实现一个具体类, 可是Java帮我们做了这件事, 如果你开发经验足够丰富的话,有反编译经验, 就会看到在一些jar包里有大量 12为后缀class文件, 其实这些都是匿名内部类来着

71830
  • 匿名内部类导致内存泄露面试题

    所以引用关系链上最终Activity对象在没有被回收情况下越来越多,就会导致OOM。 But why? 为什么持有外部类? 其实这是个值得思考问题,理清这个问题也就明白匿名内部类设计初衷了。...非静态匿名内部类持有外部类可以总结为以下两个作用 · 当类B仅在类A使用,匿名内部类可以让外部不知道类B存在,从而减少代码维护 · 类B持有类A,那么B就可以使用A中变量,比如上面的代码,在Runnable...既然 $1 是匿名内部类 class文件,那么看它字节码可以看明白 $ javap -c NonStaticInnerDemo\$1.class Compiled from "NonStaticInnerDemo.java...到这里就明白了为什么非静态匿名内部类导致内存泄露了。 那么为什么静态匿名内部类不会呢?...总结 Java匿名内部类代码更容易维护更清晰,但是非静态部类持有外部类引用,从而导致可能出现OOM。通过把内部类改为static,可以去掉对外部类引用,同时能继续使用外部类变量。

    6.6K20

    Java避坑指南:不要使用双括号初始化技巧,非静态匿名内部类可能导致内存泄露,发生OOM

    如过运行时大量生成类,导致占用大量JVM内存,甚至OOM发生,尤其是非静态匿名内部类,这个在Android开发中经常碰到。...非静态匿名内部类为什么会发生内存泄露,分析示例代码: package com.renzhikeji.demo; import java.util.HashMap; import java.util.Map...,本该被回收,却因为内部类隐式强引用外部类,所以导致外部类无法被回收,从而造成了内存泄露。...如何避免非静态匿名内部类内存泄露 ---- 1、使用静态内部类,静态内部类不持有外部类引用; 2、如果要调用外部类方法或使用外部类属性,可以使用弱引用来解决; 小结 ---- Java双括号初始化技巧会导致匿名内部类生成...,大量匿名内部类一瞬间生成会对JVM垃圾回收造成影响,可能导致OOM发生; 非静态匿名内部类生成,导致此类隐式强引用外部类,如果两个类实例生命周期不一致,也导致外部类无法被回收,从而造成了内存泄露

    51220

    JAVA private私有类 默认构造函数 生成过程

    但由于java编译器生成是class文件这种中间形式代码,所以下面的讨论应该适用于任何符合java标准编译器。...对于前两个文件,了解内部类读者都会理解,但第三个类Wrapper$1作用是什么呢?...为了更简单,(也许)更清晰看到编译器生成class代码工作原理,读者可以使用java反编译器,来 看看class反编译后生成java源程序,下面是作者使用Jad反编译后生成Wrapper类代码...那么为什么编译器一定要生成Wrapper$1类,而不使用随便一个基本类型(例如byte)来作为占位符呢?...,而任何一个可以有实际值参数都会要求开辟一些内存来存放它。那么java编译器不会做优化吗?问题是java编译器最终产生只是class代码,在class代码层次,无法向虚拟机表达这样优化。

    1.9K30

    Swift vs. Kotlin 漫谈系列之类与继承

    在 JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象成员生成为真正静态方法和字段。 不过你们类方法还可以被子类重写,这个在 Java 里也不行。...如果想要让某个类可以被继承,必须要现式为该类添加 open 关键字,该关键字提供了和 Java 中 final 相反功能。 Swift: ?,为什么要区分?...这种写法在 Java 里面就是定义内部类,在 Kotlin 里面要定义内部类反而要加上 Inner 关键字。 Swift: Swift 没有内部类概念。? Kotlin: ?...在 JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象成员生成为真正 静态方法和字段。更详细信息请参见Java 互操作性一节。...} }class SomeClass: BaseClass { } 子类获得父类非 private 属性和方法 let instance = SomeClass() instance.baseFunction

    3.7K40

    永远不要使用双花括号初始化实例,否则就会OOM!

    这一点我们可以使用命令 javac 将代码编译成字节码之后发现,我们发现之前一个类被编译成两个字节码(.class)文件,如下图所示: ?...我们使用 Idea 打开 DoubleBracket$1.class 文件发现: import java.util.HashMap; class DoubleBracket$1 extends HashMap...那么问题来了,匿名内部类为什么导致内存溢出呢? 匿名内部类“锅” 在 Java 语言中非静态内部类持有外部类引用,从而导致 GC 无法回收这部分代码引用,以至于造成内存溢出。...思考 1:为什么要持有外部类? 这个就要从匿名内部类设计说起了,在 Java 语言中,非静态匿名内部类主要作用有两个。...为什么静态内部类不会持有外部类引用?

    1.7K30

    Android插件化基础3----Android编译打包流程详解

    APK打包流程图.png 整体概述如下: 1 打包资源文件生成R.java文件 2 处理aidl文件生成相应.java文件 3 编译工程源码,生成相应class文件 4 转换所有的class...对应.java文件 5、补充: 对于没有使用到aidlandroid工程,这一步可以跳过,aidl工具解析接口定义文件生成相应.java文件,供程序调用 (三)、编译工程源码,生成相应...java文件生成class文件位于工程bin\classess目录下,上面假定编译源代码时程序是基于android SDK 开发,实际开发过程中,也有可能会使用android NDK来编译native...传统aapt打包,aapt执行2次,第一次是生成R.java,参与javac编译,第二次是对res里面的资源文件进行编译,最后将Dex文件与编译好资源文件打包成apk,进行签名。...(一)、ProGurad简介 因为Java代码是非常容易反编码,况且Android开发应用程序是用Java代码,为了很好保护Java代码,我们需要对编译好class文件进行混淆。

    2.1K22

    Java——内部类详解

    局部内部类 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类区别在于局部内部类访问仅限于方法或者该作用域。...通过上面的介绍,相比你已经大致了解部类使用,那么你心里想必会有一个疑惑: 为什么成员内部类可以无条件访问外部类成员?...} protected class Inner { public Inner() { } } } 先用 javac 进行编译,你可以发现会生成两个文件...:final Outter this$0; 学过 C 朋友应该能知道,这是一个指向外部类 Outter 对象指针,也就是说编译器默认为成员内部类添加一个指向外部类对象引用,这样也就解释了为什么成员内部类能够无条件访问外部类了...System.out.println(b); }; }.start(); } } 通过 javac 编译 Outter,也会生成两个文件

    39031

    Kotlin Vocabulary | 唯一 "对象"

    接下来内容告诉大家在 Java 和 Kotlin 中实现单例区别,以及在 Kotlin 中如何在不使用 static 关键字情况下实现单例,(其实就是通过 object 关键字实现),然后为大家详解使用...上述内容就会导致大量模板代码,每次当您创建单例时就需要重复它们。对于这么一个简单任务却使用了如此繁杂代码,所以 Java 中创建单例时通常会使用 枚举。...当 Singleton 类进行初始化时候,JVM 从同步代码块中获得一个锁,如此一来,其它线程就无法访问它。...反编译 companion object 会得到一个带有私有构造函数内联类。宿主类会通过一个合成构造方法来初始化一个内部类,这个内部类只有宿主类才能够访问。...通过 object 和 companion object, Kotlin 会生成全部所需代码来实现类似 static 关键字功能。

    1.5K60

    终于明白为什么要加 final 关键字了!

    但是在 Java 8 之后,类似场景却没有再提示了: ? 难道是此类变量可以随便改动了吗?当然不是,当你试图修改这些变量时候,仍然提示错误: ?...相比之下,Kotlin 是没有这个限制: ? 原因分析 从表面上当然看不出什么原因,看看编译器做了什么工作吧!运行 javac 命令后生成了几个 .class 文件: ?...不难推断,这个 TestInnerClass$1.class 就是匿名内部类编译后文件,看看它反编译后是什么内容: ?...原来,匿名也会被当作普通类处理,只不过编译器生成它构造方法时候,除了将外部类引用传递了过来,还将基本数据类型变量复制了一份过来,并把引用数据类型变量引用也传递了过来。...情景对比 但是为什么对于 Kotlin 来说可以在匿名内部类中直接修改基本数据类型值呢?查看 Kotlin 编译后反编译回来内容: ?

    40430

    探究Kotlin局部方法

    作为编程中金科玉律,方法越小越好,相比纵向冗长代码片段,将其按照职责切分成功能单一局部方法,最后组织起来调用,让我们代码显得更加有条理和清晰。...对于不捕获局部方法要稍有不同,首先我们反编译得到对应Java代码 public static final void outMethodNonCapture(@NotNull String[] args...首先我们找到类似这样文件MainKt$outMethodCapture$1.class (其class文件按照”文件名$方法名$内部类序号”规则)。...因为这样相比捕获情况下,减少了匿名内部类生成和实例创建,理论上带来代价也更小。 考虑到上面的对比,如果在使用局部方法时,建议使用不捕获外部变量方式更加推荐。...试想一下,如果你进入一个方法,看到是一连串局部方法,可能或多或少有点别扭。 但是试想一下,既然有这样问题,为什么还要被设计成这个样子呢。

    1.2K30

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

    2 静态内部类也是在第一次用到时被加载。但是当它加载完以后就会将静态成员变量初始化,运行静态代码块,并且只执行一次。当然,非静态成员和代码块每次实例化时也执行。...与局部变量类似,局部内部类不能有访问说明符,因为它不是外围类一部分,但是它可以访问当前代码常量,和此外围类所有的成员。...有关匿名内部类实现回调,事件驱动,委托等机制文章将在下一节讲述。 Java部类实现原理 内部类为什么能够访问外部类成员?...编译后得到Main.class Main$Inner.class两个文件,反编译Main$Inner.class文件如下: [Java部类] 可以看到,内部类其实拥有外部类一个引用,在构造函数中将外部类引用传递进来...编写代码如下: [Java部类] 这段代码编译为Main.class Main$1.class两个文件,反编译Main$1.class文件如下: [Java部类] 可以看到,java将编译时已经确定值直接复制

    1.2K10

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

    2 静态内部类也是在第一次用到时被加载。但是当它加载完以后就会将静态成员变量初始化,运行静态代码块,并且只执行一次。当然,非静态成员和代码块每次实例化时也执行。...与局部变量类似,局部内部类不能有访问说明符,因为它不是外围类一部分,但是它可以访问当前代码常量,和此外围类所有的成员。...需要注意是:局部内部类只能在定义该内部类方法实例化,不可以在此方法外对其实例化。...有关匿名内部类实现回调,事件驱动,委托等机制文章将在下一节讲述。 Java部类实现原理 内部类为什么能够访问外部类成员? 定义内部类如下: ? 使用javap命令进行反编译。...编写代码如下: ? 这段代码编译为Main.class Main$1.class两个文件,反编译Main$1.class文件如下: ?

    41810

    Java 中冷门 synthetic 关键字原理解读

    大意为:由java编译器生成(除了像默认构造函数这一类)方法,或者类 2.实例 既然知道synthetic方法和synthetic类是由编译器生成,那到底编译器怎么生成这些东西,又在什么情况下会生成这些东西呢...其中,最下面的这个类文件很好解释,就是我们主class,中间文件,是我们部类,上面的文件,后面再讲,我们先看一下中间这个内部类 2.1 内部类反编译结果 用javap 反编译DemonstrateSyntheticMethods...所以,结论很清楚了,编译器为了方便内部类私有成员被外部类引用,生成了一个get方法,这可以被理解为一个trick,绕开了private成员变量限制。...3.结论 编译器通过生成一些在源代码中不存在synthetic方法和类方式,实现了对private级别的字段和类访问,从而绕开了语言限制,这可以算是一种trick。...如果同时用到了Enum和switch,如先定义一个enum枚举,然后用switch遍历这个枚举,java编译器偷偷生成一个synthetic数组,数组内容是enum实例。

    3K50

    终于明白为什么要加 final 关键字了!

    但是在 Java 8 之后,类似场景却没有再提示了: ? 难道是此类变量可以随便改动了吗?当然不是,当你试图修改这些变量时候,仍然提示错误: ?...相比之下,Kotlin 是没有这个限制: ? 原因分析 从表面上当然看不出什么原因,看看编译器做了什么工作吧!运行 javac 命令后生成了几个 .class 文件: ?...不难推断,这个 TestInnerClass$1.class 就是匿名内部类编译后文件,看看它反编译后是什么内容: class TestInnerClass$1 extends InnerClass...,只不过编译器生成它构造方法时候,除了将外部类引用传递了过来,还将基本数据类型变量复制了一份过来,并把引用数据类型变量引用也传递了过来。...情景对比 但是为什么对于 Kotlin 来说可以在匿名内部类中直接修改基本数据类型值呢?

    44730

    【读码JDK】Java synthetic介绍

    由编译器生成,在源代码中没有出现,都会被标记为  synthetic。...{ class Son { } } 我们都知道在一个内部类中,可以直接访问外部类属性和方法,因为在内部类中是存在一个外部类一个引用变量,而这个引用变量即是编译器帮我们生成、也就是一个...因为其实 name 属性是一个私有方法、外部类 Father 中却能直接访问这个属性、对于我们写代码来说、这是非常合理一个事情、但是这都是编译器默默付出、为我们生成了一个静态 package 范围方法...、还是单独定义在一个 java 文件java 可见性都是起效。...至于为啥可以在外部直接创建一个 private 实例、无外乎就是 java 编译器帮我们做了一些额外工作。 回到上面的例子中、因为 Father03Son.

    53720
    领券