首页
学习
活动
专区
工具
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类型的?

96830

匿名内部类何为匿名?

学过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文件, 其实这些都是匿名内部类来着

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

    所以引用关系链上最终的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.7K20

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

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

    56420

    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.8K30

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

    APK打包流程图.png 整体概述如下: 1 打包资源文件,生成R.java文件 2 处理aidl文件,生成相应的.java文件 3 编译工程源码,生成相应的class文件 4 转换所有的class...对应的.java文件 5、补充: 对于没有使用到的aidl的android工程,这一步可以跳过,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,也会生成两个文件

    39631

    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文件如下: ?

    41910

    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的实例。

    3.1K50

    终于明白为什么要加 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.

    54920
    领券