Java的找不到主类(Java can't find main class)

2019-06-17 21:01发布

我写了下面的Java源文件( 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

  • Hello.class
  • Hello.java

然后,从我只是跑在同一目录javac距离,我运行java Hello.class并获得:

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

Answer 1:

你的类Hello属于包com 。 所以,你的类的全名是com.Hello 。 当您使用的命令行的java调用程序,你应该提供包含您的类的完全限定类名称main方法和省略的.class,就像这样:

java com.Hello

Java程序需要这个完全限定类名来了解你指的是哪一个类。

但是,你有另一个问题。 Java程序包定位,子包,以及属于他们使用的文件系统的类。 所以,如果你有一个像封装结构com.Hello ,java程序希望找到一个名为COM名为Hello.class类文件,如:COM / Hello.class。 事实上,你可以看到在这个行为Exception ,你看; 你正确使用Hello.class,哪个Java将其解释为指定 Hello ,和一名为class ,并正在寻找的目录结构你好/类

java.lang.NoClassDefFoundError:你好/班

但是,编译器javac的默认情况下设置此目录结构。 请参阅用于javac文档 ,但最重要的一点是:当你做你的编译,您可以指定使用一个目标目录-d标志:

-d目录

设置类文件的目标目录。 目标目录必须已经存在; javac的不会创建目标目录。 如果一个类是包的一部分,javac的放在一个子目录反映包名的类文件,根据需要创建目录。 例如,如果指定-dc:\ myclasses和类被称为com.mypackage.MyClass,那么该类文件名为C:\ myclasses \ COM \ mypackage中\ MyClass.class。

如果没有指定-d,javac的把类文件在同一目录作为源文件。

以粗体显示的最后一位是初学者很多混乱的来源,是你自己的问题的一部分。

所以,你有两个选择:

  1. 在你的情况下,如果你提供的当前目录作为目标目录,像这样的罚款(周期.意味着当前目录 ):

     javac -d . Hello.java 

    如果你调用编译器就是这样,它会为你创建com目录,并把你的编译的类文件在里面,在Java程序需要找到它的方式。 然后,当你运行java如上,从C:\ tmpJava,你的程序应该执行。

  2. 你可以设置使用与包结构的目录结构中的源代码:把你的源文件Hello.java一个名为com的目录内,你的情况:C:\ tmpJava \ COM \ Hello.java。 现在,从C:\ tmpJava你可以运行你的javac编译如下:

     javac com\Hello.java 

    您还没有提供的-d标志,但是这很好,因为你自己创建的目录结构,并从上面的文档再次引用:

    如果没有指定-d,javac的把类文件在同一目录作为源文件。

    同样,当你运行java如上,你的程序应该执行。

    请注意,此第二替代是一种通常通过Java编程人员使用:源代码文件中,反映了封装结构的目录结构进行组织。

在该说明中,我们已经忽略类路径的概念。 您还需要了解的是写Java程序,但在你的只是在当前目录编译程序的情况下 - 如果按照两个备选方案编译您的类时上面的一个 - 你可以逃脱不设置classpath中,因为默认情况下,Java程序具有当前目录中的类路径。 另一句名言,这种情况一方面源自于Java文档 :

-cp类路径

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

如果-classpath和-cp未使用,CLASSPATH没有设置,则用户类路径由当前目录的(。)。

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



Answer 2:

Java命令的语法是:

java [classname]

java [filename]

java查找在其类路径中的一类,你提供的姓名的。 通常情况下,类路径包括当前目录,因此:

java Hello

...会发现Hello.class在当前目录,并运行其main()方法。

但是,如果类是在其他地方(如在一个.jar,或者在文件系统中的其他地方),你可以用CLASSPATH环境变量指定,或者在命令行:

java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello


Answer 3:

该类应该在C:\tmpjava\com\Hello.class
你应该从运行C:\tmpjavajava -cp . com.Hello java -cp . com.Hello
当你把一个类的包,它定义的类的文件结构。 即你的类在包com应在文件夹中com



Answer 4:

运行以下命令

java -cp . com.Hello


Answer 5:

java的-classpath C:\ tmpjava com.Hello



文章来源: Java can't find main class