javac和java命令在终端中

huangapple go评论55阅读模式
英文:

javac and java command in terminal

问题

  1. 当我在IntelliJ终端中输入以下内容时:

    javac MyClass.java
    java MyClass

错误:找不到或加载主类MyClass
java.lang.NoClassDefFoundError:myPackage/myClass(错误名称:MyClass)

  1. 当我在IntelliJ终端中输入以下内容时:

    javac MyClass.java
    java MyClass.java

程序成功运行,没有任何错误。

有人可以解释一下为什么会发生这种情况吗?

英文:

I have a question below. I use JDK 17.

this is my codes.

package myPackage;
 
  public class myClass {
  
  public static void main(String[] args){

    System.out.println("test");
 }
  
}

1.When I write in IntelliJ terminal:

javac MyClass.java
java MyClass

Error:Could not find or load main class MyClass
java.lang.NoClassDefFoundError: myPackage/myClass(wrong name: MyClass)

2.When I write in IntelliJ terminal:

javac MyClass.java
java MyClass.java

Program run succesfully without any error.

May somebody explain me why this happen?

Edit:
This is directory and cmd commands

答案1

得分: 1

java MyClass

这将把参数视为“完全限定名称”(Fully Qualified Name),然后在类路径(classpath)中查找该类型。它通过将FQN转换为文件名(用斜杠替换所有点,并在末尾加上.class),例如/MyClass.class,然后将该字符串附加到类路径上的所有条目来执行此操作。这通常成功,因为.(当前目录)很可能在类路径上,而且确实存在./MyClass.class,这是一个真实的文件。

然而,随后会失败:这个类文件被打开,读取,然后Java才注意到:哦,这是一个描述myPackage.myClass的类文件,而我想要的是MyClass,所以虽然找到了文件,但我不会运行它。

要使其正常工作,你需要运行java myPackage.myClass(注意这里的小写m),它将在所有类路径中寻找/myPackage/MyClass.class。为使其工作,需要同时满足[A]找到文件以及[B]该文件必须是包含package myPackage; .... class myClass {}的文件编译生成的产品。

java MyClass.java

这是完全不同的情况;javac将其视为一个特殊情况(自Java 11以来的新功能),仅用于非常基本的“我正在学习Java”或“创建一个快速演示项目”。这绕过了构建完整应用程序的所有尝试,缩短了该过程:它打开该文件,编译它,并运行其中标记为public的类,而不考虑其实际名称或包。

这种“模式”会被触发,因为参数以.java结尾并且该文件存在。

这确实有效,并能成功运行你的代码。

英文:

> java MyClass

This treats the argument as a Fully Qualified Name and looks that type up in the classpath. It does this by translating the FQN to a filename (replace all dots with slashes and stick .class at the end of it), so, /MyClass.class, and then looks for that file by appending that string to all entries on the classpath. This succeeds, in that . (the current directory) is likely on your classpath, and there is indeed ./MyClass.class - that is a real file.

However, this then fails: This class file is opened, read, and java only then notices: Ah, this is a class file describing myPackage.myClass, and I wanted MyClass, so while I found the file, I'm not going to run it.

To make it work, you'd have to run java myPackage.myClass (note the lower case m here), which will look for /myPackage/MyClass.class relative to all classpaths. For it to work it needs to [A] find the file, and [B] that file needs to be the product of compiling a file containing package myPackage; .... class myClass {} in it.

> java MyClass.java

This is something completely different; javac treats this is as a special case (new functionality since Java 11), solely intended for very bare bones "I am learning java" / "Making a quick demo project". This bypasses all attempts to build a complete application and shortcuts the process: It opens that file, compiles it, and runs that class that was in it that was public, regardless of its actual name or package.

This 'mode' is triggered because the argument ends in .java and that file exists.

This does work and runs your code fine.

huangapple
  • 本文由 发表于 2023年3月7日 13:35:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定