C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>dir Volume in drive C has no label. Volume Serial Number is 2041-64E7 Directory of C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet 2009-07-02 23:54 . 2009-07-02 23:54 .. 2004-09-06 14:57 582 WelcomeApplet.html 2004-09-06 15:04 1,402 WelcomeApplet.java 2 File(s) 1,984 bytes 2 Dir(s) 2,557,210,624 bytes free C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>javac WelcomeApplet.java C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>dir Volume in drive C has no label. Volume Serial Number is 2041-64E7 Directory of C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet 2009-07-02 23:54 . 2009-07-02 23:54 .. 2009-07-02 23:54 975 WelcomeApplet$1.class 2009-07-02 23:54 1,379 WelcomeApplet.class 2004-09-06 14:57 582 WelcomeApplet.html 2004-09-06 15:04 1,402 WelcomeApplet.java 4 File(s) 4,338 bytes 2 Dir(s) 2,557,202,432 bytes free C:\Program Files\Java\jdk1.6.0_05\CoreJava\v1\v1ch2\WelcomeApplet>
以下是该Java文件的内容:
/**
@version 1.21 2002-06-19
@author Cay Horstmann
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class WelcomeApplet extends JApplet
{
public void init()
{
setLayout(new BorderLayout());
JLabel label = new JLabel(getParameter("greeting"), SwingConstants.CENTER);
label.setFont(new Font("Serif", Font.BOLD, 18));
add(label, BorderLayout.CENTER);
JPanel panel = new JPanel();
JButton cayButton = new JButton("Cay Horstmann");
cayButton.addActionListener(makeURLActionListener(
"http://www.horstmann.com"));
panel.add(cayButton);
JButton garyButton = new JButton("Gary Cornell");
garyButton.addActionListener(makeURLActionListener(
"mailto:gary@thecornells.com"));
panel.add(garyButton);
add(panel, BorderLayout.SOUTH);
}
private ActionListener makeURLActionListener(final String u)
{
return new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
try
{
getAppletContext().showDocument(new URL(u));
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
}
};
}
}
答案 0 :(得分:58)
这些是包含anonymous inner classes的.class
个文件。
在您的示例中,WelcomeApplet.java
包含一个顶级类(称为WelcomeApplet
)和一个匿名内部类,它将存储在WelcomeApplet$1.class
中。
请注意,包含匿名内部类的文件的确切名称不是标准化的,可能会有所不同。但在实践中,我还没有看到任何其他方案,而不是这里描述的方案。
enum
are also anonymous inner classes的价值特定机构:
枚举常量的可选类主体隐式定义了一个匿名类声明(§15.9.5),它扩展了直接封闭的枚举类型。
答案 1 :(得分:24)
$ 1是您在WelcomeApplet.java
文件中定义的匿名内部类。
e.g。编译
public class Run {
public static void main(String[] args) {
System.out.println(new Object() {
public String toString() {
return "77";
}
});
}
private class innerNamed {
}
}
会导致生成Run.class
,Run$1.class
和Run$innerNamed.class
答案 2 :(得分:4)
这些是由java编译器从WelcomeApplet.java文件中的内部和静态嵌套类生成的。
答案 3 :(得分:2)
这是来自代码的“行”:
return new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
try
{
getAppletContext().showDocument(new URL(u));
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
}
};
每次调用该方法时,您声明ActionListener
您正在创建匿名内部类的实例的方式。
即使没有调用该方法,无论如何,上述行仍会被编译成匿名内部类。
答案 4 :(得分:1)
为WelcomeApplet.java源中的匿名类生成WelcomeApplet$1.class
文件(通过调用new new ActionListener() {...}
在方法调用makeURLActionListener中生成匿名类)
为了更清楚地解释,只要你有一个具体命名类的实例化,就会在编译时生成匿名类,这些类会覆盖具体类(或接口)内联的部分或全部行为,如下所示:
class HelloInternalClass {
public static final void main(String[] args) {
// print in another thread
new Thread(new Runnable() {
public void run() {
System.out.println("Printed from another thread");
}
}).start();
}
}
在上面的示例代码中,javac编译器将生成2个类文件,就像您的示例中一样:HelloInternalClass.class
和HelloInternalClass$1.class
。
此实例中的匿名类将是 Runnable 的子类,并将编译为HelloInternalClass$1.class
。顺便提一下,如果您要从上面示例中的runnable实例中询问类名(通过调用getClass().getName()
),您会发现它认为自己是“ HelloInternalClass $ 1 ”。
答案 5 :(得分:0)
创建:
public class A {
public static void main(String[] args) {
X x=new X();
X x2=new X(){
};
Class<? extends Object>c2=x2.getClass();
Class<? extends Object>s2=x2.getClass().getSuperclass();
boolean b=false;
}
private static class X{
}
}
很难从代码中看到(new X{}()
会优于new X(){}
),但x2
是A$X
的子类的实例。该子类为A$1
。