新的Java开发者经常遇到的问题是,他们的程序无法运行,并出现错误信息。 无法找到或加载主类..."。
这是什么意思,什么原因造成的,你应该如何解决?
java <class-name>
命令语法首先,你需要了解使用java
(或javaw
)命令启动程序的正确方法。
正常的语法1 是这样的。
java [ <option> ... ] <class-name> [<argument> ...]
其中<option>
是一个命令行选项(以"-"字符开头),<class-name>
是一个完全合格的Java类名,<argument>
是一个任意的命令行参数,被传递给你的应用程序。
1 - 对于"可执行"JAR文件还有第二种语法,我将在底部描述。
类的完全合格名称(FQN)的写法与你在Java源代码中的写法相同;例如。
packagename.packagename2.packagename3.ClassName
然而,某些版本的java
命令允许你使用斜线来代替句号,例如。
packagename/packagename2/packagename3/ClassName
令人困惑的是,它看起来像一个文件路径名,但并不是一个。 请注意,完全合格的名称是标准的Java术语......而不是我为了迷惑你而编造的:-) 下面是一个例子,说明 "java "命令应该是什么样的。
java -Xmx100m com.acme.example.ListUsers fred joe bert
上面的内容将导致java
命令做以下事情。
com.acme.example.ListUsers
类的编译版本。main'方法,该方法的*特征*、*返回类型*和*修饰语*由
public static void main(String[])'给出。 (注意,方法参数的名称不是签名的***部分)。String[]
传递给它。
Java找不到该类的原因java
命令无法找到该类。 事实上,信息中的"..."将是java
正在寻找的*完全合格的类名。
那么,为什么会找不到这个类呢?第一个可能的原因是,你可能提供了错误的类名。 (或者......正确的类名,但形式不对。)考虑到上面的例子,这里有各种**错误的方法来指定类名。
例子#1 - 一个简单的类名。
java ListUser
当类被声明在诸如com.acme.example
这样的包中时,那么你必须在java
命令中使用完整的类名,包括包的名称;例如
java com.acme.example.ListUser
例子#2 - 文件名或路径名而不是类名。 java ListUser.class java com/acme/example/ListUser.class
例子#3--类名的大小写不正确。 java com.acme.example.listuser
例子 #4 - 一个错别字 java com.acme.example.mistuser
例子 #5 - 一个源文件名 java ListUser.java
第二个可能的原因是,类名是正确的,但java
命令找不到这个类。 要理解这一点,你需要理解"classpath"的概念。 这一点在Oracle文档中得到了*好的解释。
java
命令文档 。
设置Classpath]2。
java
命令时是有效的。 检查目录名和JAR文件名是否正确。
1.如果classpath中存在相对的路径名,检查它们是否能正确解析......从运行java
命令时有效的当前目录。
1.检查(在错误信息中提到的)类是否可以在有效的classpath中找到。
1.请注意,Windows与Linux和Mac OS的classpath语法是不同的。(Windows的classpath分隔符是;
,其他的是:
。 如果你在你的平台上使用了错误的分隔符,你将不会得到一个明确的错误信息。 相反,你会在路径上得到一个不存在的文件或目录,它将被默默地忽略)。
原因#2a--错误的目录在classpath上当你把一个目录放在classpath上时,它在概念上对应于限定名称空间的根。 类位于该根下面的目录结构中,通过将完全合格的名称映射为路径名。 例如,如果"/usr/local/acme/classes"在类的路径上,那么当JVM寻找一个名为`com.acme.example.Foon'的类时,它将寻找一个".class"文件,其路径名为。
/usr/local/acme/classes/com/acme/example/Foon.class
如果你的类的FQN是com.acme.example.Foon
,那么JVM就会在"com/acme/example"目录下寻找"Foon.class"。
com.acme.example.Foon
类。/usr/local/acme/classes/com/acme/example/Foon.class
。/usr/local/acme/classes/com/acme/example/
。
那么。# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
注意。
在大多数Java版本中,"classpath "选项可以被缩短为 "cp"。 请查看java
、javac
等各自的手册条目。
classpath需要包括所有你的应用程序所依赖的其他(非系统)类。 (系统类是自动定位的,你很少需要关心这个问题)。 为了使主类能够正确加载,JVM需要找到。
该类本身。
超类层次结构中的所有类和接口(例如,见https://stackoverflow.com/questions/42880748)。
javac
。 然而,如果你用手来构建你的Java代码,你可以用这样的方式,让编译器没有注意到这个问题,而产生的".class"文件不在你期望的地方。
还是找不到问题吗?java -jar <jar file>
语法用于"可执行" JAR文件的替代语法如下。
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
例如
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
com.acme.example.ListUser
)和classpath。java
命令行。
但是,如果你在 IDE 背后做一些事情,仍然有可能发生这种异常。 例如,如果你以前在Eclipse中为你的Java应用程序设置了一个应用程序启动器,然后你把包含"main"类的JAR文件移到了文件系统中的另一个地方,但没有告诉Eclipse*,Eclipse就会在不知不觉中以不正确的classpath启动JVM。
简而言之,如果你在IDE中遇到这个问题,请检查一下IDE状态是否过期、项目引用是否有问题、启动器配置是否有问题。
集成开发环境也有可能只是出现了混乱。 集成开发环境是非常复杂的软件,包括许多相互作用的部分。 其中许多部分采用了各种缓存策略,以使IDE作为一个整体做出反应。 这些策略有时会出错,一个可能的症状是启动应用程序时出现问题。 如果你怀疑这种情况可能发生,值得尝试一下,比如重新启动你的IDE和重建该项目。有时,可能导致问题的原因与主类无关,我不得不通过艰难的方式来发现这一点。我移动了一个被引用的库,它给了我。
无法找到或加载主类 xxx Linux
我只是删除了那个引用,又把它加了进去,结果又能正常工作了。