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

为什么javac后加.java,java后不加.class?的更多相关文章

  1. java 安装后 不能 java javac 说找不到命令 -bash: javac: command not found

    java 安装后 不能 java javac  说找不到命令 -bash: javac: command not found 不是环境变量的问题, 直接cd到java的目录 也不能执行命令 后来发现是 ...

  2. servlet中Java连接数据库后的基本操作

    servlet中Java连接数据库后的基本操作 在eclipse中新建一个工程:login 在Server中新建一个服务器,基本的操作不用说了,在前两天的笔记中可以找到; 需要知道数据库的用户名和密码 ...

  3. 第5篇-调用Java方法后弹出栈帧及处理返回结果

    在前一篇 第4篇-JVM终于开始调用Java主类的main()方法啦 介绍了通过callq调用entry point,不过我们并没有看完generate_call_stub()函数的实现.接下来在ge ...

  4. java编译后字节码解析

    java编译后字节码解析 参考网摘: https://my.oschina.net/indestiny/blog/194260

  5. 从事三年java开发后, 我打算转人工智能

    作为一个2015年参加java培训,2016年计算机科学与技术本科毕业后一直从事java开发的程序员来说, 做出这一步真的不容易, 可是我没赶上java最火的时候,反而渐渐感受到了java的没落, 目 ...

  6. Java编译后产生class文件的命名规则

    今天刚好有同学问了下Java编译后产生的.class文件名的问题,虽然一直都在使用Java做开发,但是之前对编译后产生的.class文件名的规范也基本没做了解过,也真的是忏愧啊!今天无论如何都要总结下 ...

  7. (转)Java编译后产生class文件的命名规则

      今天刚好有同学问了下Java编译后产生的.class文件名的问题,虽然一直都在使用Java做开发,但是之前对编译后产生的.class文件名的规范也基本没做了解过,也真的是忏愧啊!今天无论如何都要总 ...

  8. NBU For Windows 更新后无法启动Java Console

    系统环境:Win Server 2016 备份软件:NBU 8.1   Case :Windows系统默认自动安装系统补丁,重启过程中自动进行了Update,打上了最新的补丁后,NBU Java Co ...

  9. Rsa加解密Java、C#、php通用代码 密钥转换工具

    之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...

  10. 监听spring加载完成后事件

    有这个想法是在很早以前了,那时的我没有接触什么缓存技术,只知道hibernate有个二级缓存.没有用过memcache,也没有使用过redis. 只懂得将数据放到数组里或者集合里,一直不去销毁它(只有 ...

随机推荐

  1. OM6621P系列国产M4F内核低功耗BLE5.1 SoC蓝牙芯片

    随着5G与物联网时代到来,智慧城市.电动出行.智能家居.可穿戴设备等应用高速发展,低功耗蓝牙技术在近几年智能化浪潮中的地位也尤为重要.OM6621P系列的开发即是为解决国内低功耗蓝牙应用设计需求,其主 ...

  2. 了解了一下Cookie

    昨天做接口测试被Cookie折腾得云里雾里的,今天下午有时间特意了解了一下. 一:Edge浏览器查看Cookie的路径:设置->Cookie和网站权限 二:一个cookies包含以下信息:(1) ...

  3. 2.mysql存储过程、存储函数与触发器

    -- 创建一个存储过程DELIMITER $CREATE PROCEDURE 存储过程名称(返回类型 参数名1 参数类型1, ....) [ ...... ]BEGIN -- 具体组成存储过程的SQL ...

  4. docker中搭建Ubuntu:16.04+python3.6+django环境

    用vim 新建一个Dockerfile和sources.list文件,在里面添加如下内容. #sources.list deb http://mirrors.163.com/ubuntu/ xenia ...

  5. 通过Container制作Image

    1.拉取tomcat镜像 docker pull tomcat docker images 2.根据tomcat镜像创建一个tomcat container docker run -d -it --n ...

  6. mysql高级函数FIND_IN_SET,ENUM和SET,LOCATE,ELT,FIELD,INTERVAL,COUNT,CAST,NULLIF,ISNULL,IFNULL,IF,CONVERT,COALESCE

    mysql高级函数FIND_IN_SET,ENUM和SET,LOCATE,ELT,FIELD,INTERVAL,COUNT,CAST,NULLIF,ISNULL,IFNULL,IF,CONVERT,C ...

  7. Web安全测试之XSS【转】

    作者: 小坦克  来源: 博客园   原文链接:http://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html XSS 全称(Cross ...

  8. 1.java 开始

    WelloWorld 随便新建一个文件夹,存放代码 新建一个java文件 编写代码 编译javac java文件,生成一个class文件 运行class文件,java class 可能遇到的情况 每个 ...

  9. 搭建webssh和nginx反向代理

    0.前置条件,centos主机安装了python3和nginx   1.安装webssh pip3 install webssh   2.添加自定义服务 systemctl cat webssh # ...

  10. python flatten()函数的作用和用法

    flatten()函数可以执行展平操作,返回一个一维数组. 函数的作用对象是数组array.矩阵mat,不能直接用于列表list. x.flatten()是把numpy对象x降低到一维,默认是按照 行 ...