Java 类文件名中的 $1 是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1075207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:13:37  来源:igfitidea点击:

What is the $1 in class file names?

javajavacanonymous-class

提问by omg

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

Here is the content of that Java file:

这是该 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:[email protected]"));
      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(); 
               }
            }
         };
   }
}

回答by jitter

The $1 are anonymous inner classes you defined in your WelcomeApplet.javafile.

$1 是您在WelcomeApplet.java文件中定义的匿名内部类。

e.g. compiling

例如编译

public class Run {
    public static void main(String[] args) {
        System.out.println(new Object() {
            public String toString() {
                return "77";
            }
        });
    }
    private class innerNamed {
    }
}

would result in Run.class, Run$1.classand Run$innerNamed.classbeing generated

将导致Run.classRun$1.classRun$innerNamed.class正在生成

回答by Joachim Sauer

Those are the .classfiles that hold the anonymous inner classes.

这些是.class保存匿名内部类的文件。

In your example WelcomeApplet.javacontains a top-level class (called WelcomeApplet) and an anonymous inner class, which will be stored in WelcomeApplet$1.class.

在您的示例中WelcomeApplet.java包含一个顶级类(称为WelcomeApplet)和一个匿名内部类,它们将存储在WelcomeApplet$1.class.

Note that the exact name of the files holding anonymous inner classes is not standardized and might vary. But in practice I've yet to see any other scheme than the one described here.

请注意,保存匿名内部类的文件的确切名称未标准化,可能会有所不同。但在实践中,除了这里描述的方案之外,我还没有看到任何其他方案。

Value-specific bodies for an enumare also anonymous inner classes:

an 的特定于值的主体enum也是匿名内部类

The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type.

枚举常量的可选类主体隐式定义了一个匿名类声明(第15.9.5 节),它扩展了直接封闭的枚举类型。

回答by Kosi2801

These are generated from the inner and static nested classes in the WelcomeApplet.java file by the java compiler.

这些是由 java 编译器从 WelcomeApplet.java 文件中的内部和静态嵌套类生成的。

See also this similar question and answer.

另请参阅此类似问答

回答by jjnguy

It is from this 'line' of code:

它来自这行代码:

return new
    ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            try
            {
                getAppletContext().showDocument(new URL(u));
            }
            catch(MalformedURLException e) 
            { 
                e.printStackTrace(); 
            }
        }
    };

The way you are declaring the ActionListeneryou are making an instance of the anonymous inner class each time that method is called.

您声明的ActionListener方式是每次调用该方法时都会创建匿名内部类的实例。

Even if the method is not called, the above line still gets compiled into an anonymous inner class no matter what.

即使没有调用该方法,无论如何,上面的行仍然会被编译成一个匿名内部类。

回答by Roland Tepp

The WelcomeApplet$1.classfile is generated for an anonymous class in the WelcomeApplet.java source (the anonymous class is generated in the method call makeURLActionListener by calling new new ActionListener() {...})

WelcomeApplet$1.class文件是为WelcomeApplet.java源码中的匿名类生成的(匿名类是在方法调用makeURLActionListener中通过调用生成的new new ActionListener() {...}

To explain more clearly, the anonymous classes are generated at compile time any time you have an instantiation of a concrete named class that overrides some or all of the behavior of the concrete class (or interface) inline like this:

为了更清楚地解释,匿名类是在编译时生成的,只要你有一个具体命名类的实例化,该类重写具体类(或接口)内联的部分或全部行为,如下所示:

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();
  }
}

In the above sample code, the javac compiler would generate 2 class files just like in your example: HelloInternalClass.classand HelloInternalClass$1.class.

在上面的示例代码中,javac 编译器将生成 2 个类文件,就像在您的示例中一样:HelloInternalClass.classHelloInternalClass$1.class.

The anonymous class in this instance would be a subclass of Runnableand would be compiled into HelloInternalClass$1.class. Incidentally, if you would ask a class name from the runnable instance in the above sample (by calling getClass().getName()) you would find that it thinks of itself as "HelloInternalClass$1".

此实例中的匿名类将是Runnable的子类,并将被编译为HelloInternalClass$1.class. 顺便说一句,如果您从上述示例中的可运行实例中询问类名(通过调用getClass().getName()),您会发现它认为自己是“ HelloInternalClass$1”。

回答by ericj

Create:

创建:

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{     
    }
}

It is hard to see from the code (new X{}()would have been better than new X(){}), but x2is an instance of a subclass of A$X. This subclass is A$1.

从代码中很难看出(new X{}()会比 更好new X(){}),但它x2A$X. 这个子类是A$1.