`

产生多于的class$*.class的原因

阅读更多
   在java中,如果在一个类中定义了内部类,刚会生成:    super&this.class的文件,如果给某个控件添加了Listener事件,则会生成    super&i.class的文件,其中i为Listener的个数。  
   例如:下面的程序:  
   import    javax.swing.*;  
   import    java.awt.*;  
   import    java.awt.event.*;  
   
   
   /**  
     *    <p>Title:    </p>  
     *    <p>Description:    </p>  
     *    <p>Copyright:    Copyright    (c)    2001</p>  
     *    <p>Company:    </p>  
     *    @author    unascribed  
     *    @version    1.0  
     */  
   
   public    class    a    extends    JFrame    {  
       JPanel    jPanel1    =    new    JPanel();  
       JButton    jButton1    =    new    JButton();  
       JButton    jButton2    =    new    JButton();  
       JButton    jButton3    =    new    JButton();  
   
       public    a()    {  
           try    {  
               jbInit();  
           }  
           catch(Exception    e)    {  
               e.printStackTrace();  
           }  
       }  
       private    void    jbInit()    throws    Exception    {  
           jButton1.setText("jButton1");  
           jButton1.addActionListener(new    java.awt.event.ActionListener()    {  
               public    void    actionPerformed(ActionEvent    e)    {  
                   jButton1_actionPerformed(e);  
               }  
           });  
           jButton2.setText("jButton2");  
           jButton2.addActionListener(new    java.awt.event.ActionListener()    {  
               public    void    actionPerformed(ActionEvent    e)    {  
                   jButton2_actionPerformed(e);  
               }  
           });  
           jButton3.setText("jButton3");  
           jButton3.addActionListener(new    java.awt.event.ActionListener()    {  
               public    void    actionPerformed(ActionEvent    e)    {  
                   jButton3_actionPerformed(e);  
               }  
           });  
           this.getContentPane().add(jPanel1,    BorderLayout.CENTER);  
           jPanel1.add(jButton1,    null);  
           jPanel1.add(jButton2,    null);  
           jPanel1.add(jButton3,    null);  
       }  
   
       void    jButton1_actionPerformed(ActionEvent    e)    {  
   
       }  
   
       void    jButton2_actionPerformed(ActionEvent    e)    {  
   
       }  
   
       void    jButton3_actionPerformed(ActionEvent    e)    {  
   
       }  
       class    b{  
       }  
       class    c{  
           class    c1{}  
       }  
   }  
   编译后生成的class文件有:  
   a.class  
   a$1.class                      //jButton1.addActionListener  
   a$2.class                      //jButton2.addActionListener  
   a$3.class                      //jButton3.addActionListener  
   a$b.class  
   a$c.class  
   a$c1.class  
   但如果a.java这样定义:  
   class    a{  
   }  
   class    b{  
   }  
   注意为同一个文件:  
   刚编译后生成b.class,a.class  
   而不是a$b.class  
   
2

beyond compare来比较两种方式的编译结果,发现多出的两个类是GameClient$1.Class和GameBoard$1.Class。反编译其中的GameClient$1.Class,得到如下结果(另一个除包名外与此相同): 
// Decompiled by DJ v 2.8.8 .54 Copyright 2000 Atanas Neshkov   Date: 2005-1-24 17:22:29
// Home Page : http://members.fortunecity.com/neshkov/dj.html   - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name:    GameClient.java
package xxx.xxx.xxx.xxx; (此处隐去相关信息)
static class
{
}

从这个代码来看,程序中好像有匿名类的使用,但查看程序的源代码,却找不到。那么这两个类究竟是怎么产生的呢,javac编译时究竟发生了什么呢? 

经过一番调查,终于定位了匿名类是如何产生的。让我们先来看看下面的代码: 
public class OuterClass {
     private InnerClass test = new InnerClass(); 
     private class InnerClass {
     }
}

你期望的编译结果可能是产生下面两个类文件:
OuterClass.class
OuterClass$InnerClass.class

而实际javac编译的结果类文件却是:
OuterClass.class
OuterClass$InnerClass.class
OuterClass$1.class

多出了OuterClass$1.class,这是因为:

当内部类是私有的且没有明确书写公有的构造函数时,那么缺省构造函数就是私有的,javac(SUN JDK 1.4)对这种情况的处理就是创建一个可以访问的带有一个参数的构造函数,而这个参数的类型是一个匿名的静态类,所以编译时就会多生成一个class文件。 

你可能使用Eclipse进行编译,那么是的,结果跟你期望的一致,没有OuterClass$1.class。这是为什么?Eclipse JDT使用的编译器与JDK提供的javac不一样?是的,Eclipse JDT使用的是它自己内建的编译器,有一些增强的功能,包括对上述情况的完美处理。 

终于明白了问题的根源在于,GameClient.java,GameBoard.java中分别有一个私有内部类没有定义构造函数。 

那么至此,这个问题给我们带来的启示是:
1、   确认项目最终使用的Java类的编译器。如果可能,尽可能使用javac生成结果应用程序,或是与客户达成一致。
2、   尽量明确的书写缺省构造函数及其可见性,如将上面的代码改为:
public class OuterClass {
     private InnerClass test = new InnerClass();

     private class InnerClass {
         public InnerClass() {
         }
     }
}

3 对于引用中的interface--impl

在实现类中没有缺省的构造函数,在调用的同时,就会产生额外的文件

分享到:
评论

相关推荐

    diffraction.zip_diffraction

    1. **DiffractionFrame$DoubleCircleAperture.class**:双圆孔模型,模拟两个相邻圆形孔径产生的复合衍射图案,这种模式可以用来研究两个孔径间的相互作用以及衍射强度的叠加效应。 2. **DiffractionFrame$...

    2016奇虎360_JAVA研发工程师内推笔试题

    属于网络`***.**.***.*/21`的地址是指该地址处于`***.**.***.*`至`***.**.***.***`的范围内,其中`***.**.***.*`和`***.**.***.*`不在该范围内。 6. Java程序执行结果 ```java import java.util.HashMap; public ...

    windows操作系统中的系统属性.docx

    17. **java.io.tmpdir** - 默认的临时文件路径,通常用于存放程序运行过程中产生的临时文件。 18. **java.compiler** - 要使用的JIT编译器的名称,如果未设置则可能为空字符串。 19. **java.ext.dirs** - 一个或多个...

    如何在netbeans下把java工程打包成jar包

    ${store.dir}/temp_final.jar" excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/&gt; ${store.dir}/temp_final.jar"/&gt; ``` 其中,`&lt;property name="store.jar.name" value="MyJarName"/&gt;`中的值可以...

    class反编译.7z

    当Java源代码(.java文件)被Javac编译器处理后,会产生对应的字节码文件(.class文件)。这些字节码文件是平台无关的,并且可以由Java虚拟机(JVM)执行。字节码文件不包含原始的源代码,因此无法直接阅读。 Java...

    JAVA里的一些经典习题

    - **答案解析:**.class。Java源代码文件编译后形成的字节码文件扩展名为`.class`。 **9. 执行模式的另一半** - **答案解析:**半解释型。Java的执行模式是半编译和半解释型。 **10. 类库的特点** - **答案解析:*...

    如何将.class文件打成jar包

    - `*.class` 表示将所有 `.class` 文件打包到 `jar` 文件中。 #### 更多 `jar` 命令选项 除了上述的基本用法外,`jar` 命令还支持其他选项,可以帮助完成更复杂的任务: - **`-t`**:列出 `jar` 文件的内容。 - ...

    一个最简单的聊天程序

    在这个系统中,Server.java和Client.java是主要的源代码文件,而其他以"$"符号命名的.class文件是由于Java的内部类编译后产生的结果。 1. **Socket编程**: Socket是网络通信中的基本概念,它是连接客户端和服务器...

    面向对象C++用虚继承来消灭菱形结构二义性,解决俩爷爷的问题.zip

    class Father1 : public Grandfather { /*...*/ }; class Father2 : public Grandfather { /*...*/ }; class Son : public Father1, public Father2 { /*...*/ }; ``` 在这个例子中,`Son` 类有两个 `Grandfather`...

    新东方JAVA培训 月考题目(选择部分)

    3. **产生Java文档**:使用`javadoc`命令,这会生成API文档,如`javadoc -d docs HelloWorld.java`。 4. **查询是否可序列化**:使用`serialver`命令,检查类是否实现了`Serializable`接口。 5. **产生Java安全策略...

    java-class-decompile.rar_class_site:www.pudn.com

    Java类文件(.class)是Java源代码经过编译后的二进制表示,它包含了运行在Java虚拟机上的指令和元数据。当我们只有.class文件而没有原始的.java源代码时,有时我们需要反编译这些文件以理解其内部逻辑。本文将深入...

    专题资料(2021-2022年)[东北大学]考试《Java语言程序设计I》考核作业.doc

    因此,对于5个类的源文件,将产生5个`.class`文件。正确答案是**D. 5 个字节码文件,扩展名为.class**。 8. **创建数组**:在Java中,创建二维数组的正确方式是`float [][]f = new float[6][6];`。正确答案是**D**...

    [php]mysql数据库操作——DB类

    class mysql{ private $host; // 数据库主机 private $user; // 数据库用户名 private $pass; // 数据库密码 private $data; // 数据库名 private $conn; // 数据库连接标识 private $sql; // sql语句 ...

    jQuery图片列表 点击 后图片放大 动画

    jQuery库通过$(document).ready()函数来确保页面加载完成后再执行脚本,这样可以避免因元素未加载完全而产生的错误。例如: ```javascript $(document).ready(function() { // 在这里编写你的代码 }); ``` 接着,...

    输出JDK和CGLib动态代理产生的class文件.zip

    本压缩包文件提供了两个示例项目,分别展示了JDK动态代理和CGLib动态代理的实现,帮助我们理解这两种技术的工作原理以及它们生成的class文件结构。 首先,我们来详细了解JDK动态代理。JDK动态代理基于Java的接口...

    C++编程基础教程.docx

    - 类模板:`template&lt;typename T&gt; class MyContainer { ... };` **2. 数据结构** - 线性表:顺序存储和链式存储。 - 查找方法:顺序查找、二分查找。 - 排序方法:冒泡排序、选择排序、插入排序等。 **3. 索引查找...

    jquery控制大图缩放轮播显示焦点图banner

    这样,当图片切换时,新的图片将会放大以产生更吸引人的过渡效果。当然,你可以根据需求调整缩放比例和其他动画参数。 此外,你可能还需要考虑触摸设备的支持,添加滑动手势来切换图片,以及添加键盘导航等增强用户...

    java class反编译工具

    Java Class反编译工具是程序员在处理已编译的字节码文件时不可或缺的辅助工具。这类工具的主要功能是将`.class`文件转换回可读性强的`.java`源代码,帮助开发者理解或修改已有的Java程序,尤其在没有源代码的情况下...

    使用SVN,Ant制作发布版本

    ${src.dir}/resources" includes="**/*.txt,**/*.xml,**/*.dat,**/*.dll,**/*.properties" /&gt; ``` 4. **更新配置文件**:在发布版本前,可能还需要更新某些配置文件中的参数,比如数据库连接字符串或服务器...

    OpenGL 3D立方体多纹理贴图.zip

    在顶点着色器中,我们传递纹理坐标,而在片段着色器中,我们可以使用`texture2D()`函数采样多个纹理并结合它们,以产生最终的颜色。 总之,这个项目为学习OpenGL ES在Android上的3D图形编程提供了一个实际的例子,...

Global site tag (gtag.js) - Google Analytics