关于java文件编译后,同一个文件出现"$"的class
2011-06-08 15:00
696 查看
在java中,如果在一个类中定义了内部类,刚会生成: super&this.class的文件,如果给某个控件添加了Listener事件,则会生成 super&i.class的文件,其中i为Listener的个数。 例如:下面的程序: import javax.swing.*; import java.awt.*; import java.awt.event.*; /** *
Title:
*
Description:
*
Copyright: Copyright (c) 2001
*
Company:
* @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 在实现类中没有缺省的构造函数,在调用的同时,就会产生额外的文件
Title:
*
Description:
*
Copyright: Copyright (c) 2001
*
Company:
* @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 在实现类中没有缺省的构造函数,在调用的同时,就会产生额外的文件
相关文章推荐
- 关于java文件编译后,同一个文件出现"$"的class
- java文件编译后,同一个文件出现"$"的class
- 关于svn上传的代码每个java文件上都出现class问件暨代码编译路径的若干问题
- 关于反编译apk出现Exception in thread "main" java.lang.ClassCastException: ....
- 关于命令行中javac 编译成功,用 java 运行 class 文件出现 “ 找不到或无法加载主类 ” 的问题
- java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
- IDEA java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
- 编译运行java程序出现Exception in thread "main" java.lang.UnsupportedClassVersionError: M : Unsupported major.minor version 51.0
- javac 编译源文件出现"java:1: 需要为 class、interface 或 enum"、" [javac] 锘縫"错误
- 驱动工程中添加新文件后出现的“cannot open source file '***.tmh'"编译错误
- 关于在Java中使用request.getRequestDispatcher(".....")引起的css文件无效或图片无效问题。
- "java.lang.NoClassDefFoundError"错误——一个关于classpath设置的问题
- 用gcc编译.cpp文件可能出现"undefined reference to `__gxx_personality_v0'"问题的解决
- 用anjuta编译gtk程序时出现类似与"main.c::10:21:gtk/gtk.h:没有那个文件和目录"问题的解决
- 【JAVA学习】读取文件getClassLoader().getResourceAsStream("xxx")
- javac编译成功,用java运行class文件出现“找不到或无法加载主类” 的问题
- 关于使用cmd编译java文件出现乱码现象解决方法
- javac编译成功,用java运行class文件出现“找不到或无法加载主类” 的问题
- jsp文件头部出现红叉解决方法The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 关于写入文件缓存时报"java.io.FileNotFoundException open failed (is a director)"错误的解决方法