Java无法找到主类 [英] Java can't find main class

查看:128
本文介绍了Java无法找到主类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下Java源文件( Hello.java ):

I have written the following Java source file (Hello.java):

package com;

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

我将此保存到 C :/tmpjava/Hello.java

从命令行,我导航到该目录并运行 javac Hello的.java 。然后我运行 dir

From the command line, I navigate to that directory and run javac Hello.java. Then I run dir:


  • Hello.class

  • Hello.java

  • Hello.class
  • Hello.java

然后,从我刚刚运行的 javac 的同一目录中,运行 java Hello.class 并获取:

Then, from the same directory that I just ran javac from, I run java Hello.class and get:

Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Hello.class.  Program will exit.

这里发生了什么?!?如何 javac 运行正常,但不是 java

What's going on here?!? How can javac run fine, but not java?

推荐答案

您的班级 Hello 属于 com 包。因此,您的类的完全限定名称是 com.Hello 。在命令行上使用java调用程序时,应提供包含 main 方法的类的完全限定类名,并省略。 class ,如下所示:

Your class Hello belongs to the package com. So the fully qualified name of your class is com.Hello. When you invoke a program using java on the command-line, you should supply the fully-qualified class name of the class that contains your main method and omit the .class, like so:

java com.Hello

java程序需要这个完全限定的类名才能理解你所指的类。

The java program needs this fully-qualified class name to understand which class you are referring to.

但是你有另一个问题。 java程序使用文件系统定位包,子包和属于它们的类。因此,如果您有一个类似 com.Hello 的包结构,那么java程序希望在名为<的目录中找到名为 Hello.class 的类文件。 em> com ,如下所示: com / Hello.class 。实际上,您可以在您看到的 Exception 中观察到此行为;您错误地使用了 Hello.class ,java正在将其解释为名为 Hello ,以及 class 命名为 class ,并且正在寻找目录结构 Hello / class

But you have another problem. The java program locates packages, sub-packages, and the classes that belong to them using the filesystem. So if you have a package structure like com.Hello, the java program expects to find a class file named Hello.class in a directory named com, like this: com/Hello.class. In fact you can observe this behavior in the Exception that you see; you've incorrectly used Hello.class, which java is interpreting as a package named Hello, and a class named class, and is looking for the directory structure Hello/class:


java.lang.NoClassDefFoundError:Hello / class

java.lang.NoClassDefFoundError: Hello/class

但编译器javac 默认情况下设置此目录结构。请参阅 javac的文档,但重要的是bit是这样的:当你进行编译时,可以使用 -d 标志指定目标目录:

But the compiler javac doesn't set up this directory structure by default. See the documentation for javac, but the important bit is this: when you do your compiles, you can specify a destination directory using the -d flag:


-d directory

-d directory

设置类文件的目标目录。目标目录必须已存在; javac不会创建目标目录。如果类是包的一部分,则javac将类文件放在反映包名的子目录中,根据需要创建目录。例如,如果指定-dc:\ myclasses并且该类名为com.mypackage.MyClass,则该类文件名为c:\ myclasses \ com \ myscackage \ MyClass.class。

Set the destination directory for class files. The destination directory must already exist; javac will not create the destination directory. If a class is part of a package, javac puts the class file in a subdirectory reflecting the package name, creating directories as needed. For example, if you specify -d c:\myclasses and the class is called com.mypackage.MyClass, then the class file is called c:\myclasses\com\mypackage\MyClass.class.

如果未指定-d,则javac将类文件放在与源文件相同的目录中。

粗体的最后一位是初学者混淆的根源,也是你自己问题的一部分。

The last bit in bold is the source of much confusion for beginners, and is part of your own problem.

所以您有两种选择:


  1. 在您的情况下,如果您将当前目录作为目标目录提供,则可以(如此)期间表示当前目录):

javac -d . Hello.java

如果像这样调用编译器,它将创建 com 目录,并将编译后的类文件放入其中,这是java程序期望找到它的方式。然后当您运行上面的java时,从 c:\ tmpJava ,你的程序应该执行。

If you invoke the compiler like this, it will create the com directory for you, and put your compiled class file in it, the way that the java program expects to find it. Then when you run java as above, from c:\tmpJava, your program should execute.

你可以设置你的使用镜像包结构的目录结构的源代码:将源文件 Hello.java 放在名为 com 的目录中,在您的情况下: c:\ tmpJava\com\Hello.java 。现在,从 c:\ tmpJava 你可以像这样运行你的javac编译:

You could set up your source code using a directory structure that mirrors your package structure: put your source file Hello.java inside a directory called com, in your case: c:\tmpJava\com\Hello.java. Now, from c:\tmpJava you can run your javac compile like this:

javac com\Hello.java

您还没有提供 -d flag,但没关系,因为你自己创建了目录结构,并再次从上面的文档中引用:

You haven't supplied the -d flag, but that's fine, because you've created the directory structure yourself, and quoting again from the documentation above:


如果未指定-d,则javac将类文件放在与源文件相同的目录中。

If -d is not specified, javac puts the class file in the same directory as the source file.

再次,当您运行时java如上所述,你的程序应该执行。

Again, when you run java as above, your program should execute.

注意,第二种方法是java程序员常用的方法:源代码文件组织在一个目录结构中,镜像包结构。

Note that this second alternative is one that is commonly employed by java programmers: the source code files are organized in a directory structure that mirrors the package structure.

在这个解释中,我们忽略了 classpath 的概念。您还需要了解编写java程序,但在您编写当前目录中的程序时 - 如果您在编译类时遵循上述两种选择之一 - 您可以在不设置类路径的情况下逃脱,因为默认情况下,java程序将当前目录作为类路径。另一个引用,来自 java的文档

In this explanation we've ignored the concept of the classpath. You'll also need to understand that to write java programs, but in your case of simply compiling a program in the current directory - if you follow one of the two alternatives above when compiling your class - you can get away without setting a classpath because, by default, the java program has the current directory as a classpath. Another quote, this one from the documentation for java:


-cp classpath

-cp classpath

指定目录列表,JAR档案和ZIP存档以搜索类文件。类路径条目由分号(;)分隔。指定-classpath或-cp会覆盖CLASSPATH环境变量的任何设置。

Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons (;). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.

如果未使用-classpath和-cp且未设置CLASSPATH,则用户类路径包含当前目录(。)。

请注意,当您使用像Eclipse这样的IDE来运行时java代码,这主要是为你处理的,但你仍会遇到类路径问题。

Note that when you use an IDE like Eclipse to run your java code, this is mostly handled for you, but you'll still run into classpath issues.

这篇关于Java无法找到主类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆