JVM是运行java字节码的虚拟机,jvm有针对不同系统的特定实现,目的是使用相同的字节码,它们都会给出相同的结果。(屏蔽了底层操作系统和硬件的差异,每个平台下载个虚拟机就可)
何为字节码?它的好处是啥?
java中,jvm可以理解的代码叫做字节码(扩展名为.class的文件),它不面向任何特定的处理器,只面向虚拟机。java语言通过字节码方式在一定程度上解决了传统解释器语言执行效率低的问题,同时又保留了解释器语言可移植的特点,因此java程序运行时比较高效,而且,由于字节码不针对一种特定机器,因此java无须重新编译就可在多种不同操作系统的计算机上运行。
java从源代码到运行一般三步,.java文件(源代码)通过JDK的javac编译成.class文件(jvm可理解的java字节),然后通过jvm转换成机器可执行的二进制机器码(计算机可理解的)。
在讨论一些问题前先来介绍些基本知识
编译器和解释器区别:解释器是一条一条的解释执行源语言,每次运行一段程序都需要重新编译一次导致每次运行到这段程序时都会重新编译一次,这样开销会很大,编译器则是把源代码整个编译成目标代码,执行时不再需要编译器,直接在支持目标代码的平台上运行,这样执行效率比解释效率快很多,比如c语言代码被编译成二进制代码(计算机读懂的语言),在windows上运行。
编译器执行效率远远大于解释器,但由于不同操作系统计算机识别二进制文件(机器语言)是不同的,所以程序进行移植其他平台需要重新编译,对平台依赖性强,不适合跨平台开发。
所以为啥说php,javascript,python这些语言具有跨平台性,因为如果平台上有这些语言的解释器,只需要在平台上运行就可以了不像c语言还得有编译链接工序,很方便。这几种语言也不可能是纯解释器,因为效率太低了,只有javascript这种不会太长的语言才会采用纯解释器,由于浏览器的差异,也决定了javascript的跨平台性,这里为了举个例子都算在内。
这回回到java这里,java采用的是这种预编译,中间代码就是字节码,有了字节码就避免了上面纯解释器编译源代码的大开销,效率会提高一些。
解释器就像翻译官
.class字节码到机器码这一步jvm类加载器首先加载字节码文件,然后中间代码解释器逐行解释执行,这种方式比较慢。有些方法和代码块经常需要被调用(称为热点代码),所以针对这阵情况引进了JIT编译器(即时编译器),JIT属于运行时编译,当JIT完成第一次编译后,其会将字节码对应的机器码保存下来,下次直接使用,因为机器码的运行效率比java解释器高所以就解释了java是编译与解释共存的语言(前半部分编译后半部分解释)。
然后介绍下jdk和jre
jdk是功能齐全的javaSDK,拥有jre的一切,还有javac编译器和jdb,javadoc工具,能够创建和编译程序。
jre是java运行时环境,运行已编译java程序所需的所有内容集合,包括jvm,java类库等等,但不能创建新程序,只是运行下java,安装个jre就可以了。
最好还是安个jdk最好,就算不做java开发,如果使用jsp部署web应用程序,应用程序服务器会将jsp转换成java servlet,需要jdk来编译servlet。
都是面向对象语言,都可封装继承多态
java不提供指针来直接访问内存,程序内存更安全
java的类不支持多继承,c++支持,但java接口可以多继承
java自动内存管理垃圾回收,无需手动释放无用内存
这个上面解释过,再具体说一遍。
高级编程语言按照程序的执行方式分为编译型和解释型两种。简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。比如,你想阅读一本英文名著,你可以找一个英文翻译人员帮助你阅读, 有两种选择方式,你可以先等翻译人员将全本的英文名著(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。
Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(*.class 文件),这种字节码必须由 Java 解释器来解释执行。因此,我们可以认为 Java 语言编译与解释并存。