【问题标题】:Multiple classes in a single Java file, each with a main method - unexpected behavior?单个 Java 文件中的多个类,每个类都有一个 main 方法 - 意外行为?
【发布时间】:2011-08-11 09:33:03
【问题描述】:

我在目录 C:\D\JavaProjects 中名为 test.java 的文件中有以下代码

class test
{
        public static void main( String[] str )
        {
                System.out.println( "Hello, World! from test" );
        }
}

class Test
{
        public static void main( String[] str )
        {
                System.out.println( "Hello, World!" );
        }
}

当我执行“javac test.java”时,它会输出 test.class。现在,如果我执行“java test”,我会得到以下输出:

线程“主”java.lang.NoClassDefFoundError 中的异常:测试(错误名称:测试) 在 java.lang.ClassLoader.defineClass1(本机方法) 在 java.lang.ClassLoader.defineClassCond(未知来源) 在 java.lang.ClassLoader.defineClass(未知来源) 在 java.security.SecureClassLoader.defineClass(未知来源) 在 java.net.URLClassLoader.defineClass(未知来源) 在 java.net.URLClassLoader.access$000(未知来源) 在 java.net.URLClassLoader$1.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.net.URLClassLoader.findClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) 在 sun.misc.Launcher$AppClassLoader.loadClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) 找不到主类:test。程序将退出。

但是当我做“java测试”时,我得到了

你好,世界!

现在,如果我简单地颠倒两个类声明的出现,例如在测试之前声明 Test,java 编译器会输出文件 Test.class。现在做“java test”会给出输出:

你好,世界!来自测试

但是“java Test”给出了

线程“主”java.lang.NoClassDefFoundError 中的异常:测试(错误名称:测试) 在 java.lang.ClassLoader.defineClass1(本机方法) 在 java.lang.ClassLoader.defineClassCond(未知来源) 在 java.lang.ClassLoader.defineClass(未知来源) 在 java.security.SecureClassLoader.defineClass(未知来源) 在 java.net.URLClassLoader.defineClass(未知来源) 在 java.net.URLClassLoader.access$000(未知来源) 在 java.net.URLClassLoader$1.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.net.URLClassLoader.findClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) 在 sun.misc.Launcher$AppClassLoader.loadClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) 找不到主类:测试。程序将退出。

现在,我知道在同一个文件中有两个带有 main 的类是很奇怪的,但这种行为似乎完全不合逻辑,更像是一个错误。有人可以指出指定此行为的 Java 语言规范的适当部分吗?非常感谢您的帮助。

【问题讨论】:

标签: java main


【解决方案1】:

大概你在 Windows 上运行,对吧?

这意味着你不能有两个只区分大小写的类——因为它们最终都希望在同一个文件中,因为Test.classtest.class 在不区分大小写的情况下实际上是相同的文件名文件系统。

这并不是 Java 中的真正错误 - 只是将不区分大小写的文件系统与将含义附加到文件名的语言结合使用的不幸但自然的必然结果。

【讨论】:

  • 是的,没错。我在 Windows 7 上运行。感谢您的快速回复!!!所以大概是,当我先声明了 Test 然后再进行测试时,它首先输出 Test.class,然后尝试创建 test.class 但发现 Test.class 已经创建,因此打开它并将 test 输出到该文件中。现在当我做java测试时,它会找到Test.class(因为文件系统不区分大小写)并在其中找到test并成功运行!!!!但我仍然说这是一个错误。因为这意味着有人在 fopen/_open/CreateFile 中使用了表示打开现有文件(如果已创建)的标志。哈哈!!!
  • @dark_secrets:如果任何输出文件已经存在,您是否希望编译失败?对我来说听起来是个坏主意。
  • 不,他们应该使用 fopen/_open/CreateFile 中覆盖已创建文件的标志。
  • @dark_secrets:我认为它已经覆盖了它。它不是附加它 - 它是用 Test 类覆盖 test 类。从根本上说,您尝试存储两种不同的内容,但您只有一个文件可以放入它们。您希望它如何工作?
【解决方案2】:

@dark_secrets,在 JAVA 中,类名必须以大写字母开头,否则编译时会出错。

【讨论】:

    【解决方案3】:

    使用公共(然后是类名)....这将绝对有效....

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2014-08-13
      • 2020-07-04
      • 1970-01-01
      相关资源
      最近更新 更多