单个 Java 文件中的多个类,每个类都有一个 main 方法 - 意外行为?
我在名为 test.java 的文件中获得了以下代码,该文件位于目录 C:\D\JavaProjects 中。
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”,我会得到以下输出:
线程“main”java.lang.NoClassDefFoundError中出现异常:test(错误名称:Test) 在 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”时我得到
你好,世界!
现在,如果我简单地颠倒两个类声明的出现,使得 Test 在 test 之前声明,则 java 编译器会输出文件 Test.class。现在执行“java test”给出输出:
你好,世界!来自测试
,但“java Test”给出
线程“main”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。程序将退出。
现在,我知道在同一个文件中包含两个带有 main 的类是非常奇怪的,但这种行为似乎完全不合逻辑,更像是一个错误。有人可以指出 Java 语言规范中指定此行为的相应部分吗?非常感谢您的帮助。
I have got the following code in a file called test.java which is located inside the directory C:\D\JavaProjects
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!" );
}
}
When I do "javac test.java" it outputs test.class. Now, if I do "java test" I get the following output:
Exception in thread "main" java.lang.NoClassDefFoundError: test (wrong name: Test)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: test. Program will exit.
But when I do "java Test" I get
Hello, World!
Now, if I simply reverse the occurrence of the two class declarations, such that Test is declared BEFORE test, the java compiler outputs the file Test.class. Now doing "java test" gives the output:
Hello, World! from test
but "java Test" gives
Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: test)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: Test. Program will exit.
Now, I know it is very strange to have two classes with main in them in the same file, but this behavior seems completely illogical and more like a bug. Can somebody point me to the appropriate section of the Java Language Specification that specifies this behavior? Many thanks in advance for the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
想必您正在 Windows 上运行,对吧?
这意味着您不能拥有两个仅大小写不同的类 - 因为它们最终都希望位于同一个文件中,如
Test.class
和test.class 在不区分大小写的文件系统中实际上是相同的文件名。
这并不是 Java 中的一个真正的错误——只是将不区分大小写的文件系统与赋予文件名含义的语言结合使用的一个不幸但自然的必然结果。
Presumably you're running on Windows, right?
That means you can't have two classes which differ only in case - because they'll both end up wanting to be in the same file, as
Test.class
andtest.class
are effectively the same filename in case-insensitive file systems.It's not really a bug in Java - just an unfortunate but natural corollary of using a case-insensitive file system in conjunction with a language which attaches meaning to filenames.
@dark_secrets,在JAVA中类名必须以大写字母开头,否则编译时会出错。
@dark_secrets, You have to begin a class name with a capital letter in JAVA or else you will get an error while compiling.
使用 public (然后是类名)......这肯定会起作用......
use public (then class name).... that will definetely work....