Javac和java命令的用法:javac需要文件,Java需要执行类或jar文件
javac用法:

java用法

例子

Java命令后的“test.Test.class”会被认为是包含main方法的主类,但是JVM去加载该类时找不到该类。

有如下的一些解释:

  • 编译时,添加后缀表示把一个文件(即扩展名为Java的文件)转换为字节码,之后,运行时,运行的不是文件,而是文件的类名称,因为主类和类名保持一致,所以你运行输入的Test是类名,而不是扩展名;
  • 《深入理解Java虚拟机》第六章图示6-1中各种可以编译为class字节码的语言都有对应的编译器,编译Java程序的编译器为javac编译器,即为Java compiler的简称.

疑问:

既然javac是编译Java程序的编译器,它的输入一定是.java文件,为什么不把后缀名去掉?
javac命令和Java命令一个带后缀名一个不带后缀名是为什么?

多种文件均可以编译为class字节码,每种语言都有不同的后缀名和对应的编译器,但是为什么编译器不省略掉后缀名?难道javac编译器还可以编译其他后缀名的文件?
如果从另一方面看,带上后缀名是正常操作,那么问题就是Java命令为什么去掉了.class后缀?
这和Java虚拟机的规范有关,class文件是Java虚拟机执行引擎的数据入口,所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果。Java命令后为类名或jar文件,即它有.class、.jar形式。

stackoverflow上找到一个解释如下:
https://stackoverflow.com/questions/8651140/why-compiler-needs-java-suffix-but-interpreter-doesnt-need-class-suffix

As a couple of other answers have explained, the Java compiler takes a file name as an argument, whereas the interpreter takes a class name.

So you give the .java extension to the compiler because it's part of the file name, but you don't give it to the interpreter because it's not part of the class name.

But then, you might wonder, why didn't they just design the Java interpreter differently so that it would take a file name? The answer to that is that classes are not always loaded from .class files. Sometimes they come from JAR archives, sometimes they come from the internet, sometimes they are constructed on the fly by a program, and so on. A class could come from any source that can provide the binary data needed to define it. Perhaps the same class could have different implementations from different sources, for example a program might try to load the most up-to-date version of some class from a URL, but would fall back to a local file if that failed. The designers of Java thought it best that when you're trying to run a program, you don't have to worry about having to track down the source that defines the class you're running. You just give the fully qualified class name and let Java (or rather, its ClassLoaders) do the hard work of finding it.

正如其他几个答案所解释的那样,Java 编译器采用文件名作为参数,而解释器采用类名。因此,您将 .java 扩展名提供给编译器,因为它是文件名的一部分,但您没有将其提供给解释器,因为它不是类名的一部分。
但是,您可能想知道,为什么他们不设计不同的 Java 解释器,以便它采用文件名?答案是类并不总是从 .class 文件加载。有时它们来自 JAR 包,有时它们来自互联网,有时它们是由程序动态构建的,等等。一个类可以来自任何可以提供定义它所需的二进制数据的来源。也许同一个类可能有来自不同来源的不同实现,例如,程序可能会尝试从 URL 加载某个类的最新版本,但如果失败,则会回退到本地文件。 Java 的设计者认为,当您尝试运行程序时,最好不必担心必须追踪定义您正在运行的类的源代码。您只需给出完全限定的类名,然后让 Java(或者更确切地说,它的 ClassLoader)来完成查找它的艰苦工作。

此外JDK的javac命令是字节码生成技术的“老祖宗”,并且javac也是一个由Java语言写成的程序,它的代码存放在OpenJDKde langtools/src/share/classes/com/sun/tools/javac目录中。

http://hg.openjdk.java.net/jdk8u/jdk8u60/langtools/file/b9abf5c3d057/src/share/classes/com/sun/tools/javac

最新文章

  1. .NET Core RC2发布在即,我们试着用记事本编写一个ASP.NET Core RC2 MVC程序
  2. x01.Weiqi.7: 调整重绘
  3. 一行python代码实现树结构
  4. 注意HTML的语言编码charset
  5. .Net操作Excel
  6. linux 定时执行任务 crontab
  7. 解决Discuz“完善用户资料”任务不能完成的问题
  8. Arcgis投影变换后图像变深的问题
  9. VM虚拟机上 实现CentOS 6.X下部署LVS(DR)+keepalived实现高性能高可用负载均衡
  10. 利用fiddler和mock调试本地微信网页
  11. ElasticSearch搜索(一)
  12. JS循环语句!
  13. A1100. Mars Numbers
  14. Linux下Shell命令加减乘除计算
  15. 利用bat批处理做启动mongodb脚本
  16. [翻译] Rails::Railtie
  17. 3991: [SDOI2015]寻宝游戏
  18. Java io流详解二
  19. oracle加入not null约束
  20. vue axios 攻略

热门文章

  1. uniapp组件监听onShow
  2. [转载] MATLAB | RGB image representation
  3. windows下BAT实现守护进程
  4. 查看oracle死锁
  5. java中取整数绝对值_Java之——位运算求整数绝对值通过下面的位运算可以得到一个整数的绝对值
  6. https://github.com/wuweilin/springboot-login-demo
  7. django解决网站CORS前后端跨域问题
  8. Oracle.DataAccess使用问题汇总
  9. python os.path模块函数功能
  10. 【FPGA学习】根据datasheet编写Verilog驱动(PCF8574 IO扩展板练习)