第一次写博客,记录一下刚刚看的一点东西吧,在转载的基础上做了一些修改..
编译型语言和解释型语言的区别
首先,计算机只能理解机器语言,不能直接理解高级语言,所以在高级语言(即除了汇编语言和机器语言)编写的程序必须先被翻译成机器语言才能被计算机系统识别和执行。
翻译有两种方式:编译和解释,两种方式的区别只在于他们翻译的时间不同。
编译型语言编写的程序,需要在编写完成后,便通过编译器将高级语言代码文件编译成机器语言代码文件,而在系统运行该文件的过程中,就无需再次翻译了,故编译型语言编写的程序执行效率会相对较高。(总结就是编译型语言在运行前翻译,效率高,但是因为编译前无法得知运行环境的情况,故不能跨平台执行)
解释型语言编写的程序则不同,他在运行之前,不需要编译就可直接运行,但在运行过程中,还是会有一个编译器对将程序编译成机器语言代码,并且是执行一句翻译一句,每句都要翻译,故解释型语言运行效率较低。
编译型与解释型,两者各有利弊。前者由于程序执行速度快,同等条件下对系统要求较低,因此像开发操作系统、大型应用程序、数据库系统等时都采用它,像C/C++、Pascal/Object Pascal(Delphi)等都是编译语言,而一些网页脚本、服务器脚本及辅助开发接口这样的对速度要求不高、对不同系统平台间的兼容性有一定要求的程序则通常使用解释性语言,如JavaScript、VBScript、Perl、Python、Ruby、MATLAB 等等。
但随着硬件的升级和设计思想的变革,编译型和解释型语言越来越笼统,主要体现在一些新兴的高级语言上,而解释型语言的自身特点也使得编译器厂商愿意花费更多成本来优化解释器,解释型语言性能超过编译型语言也是必然的。
java和c#的语言性质
JAVA语言是一种编译型-解释型语言,同时具备编译特性和解释特性(其实,确切的说java就是解释型语言,其所谓的编译过程只是将.java文件编程成平台无关的字节码.class文件,并不是向C一样编译成可执行的机器语言,在此请读者注意Java中所谓的“编译”和传统的“编译”的区别)。作为编译型语言,JAVA程序要被统一编译成字节码文件——文件后缀是class。此种文件在java中又称为类文件。java类文件不能再计算机上直接执行,它需要被java虚拟机翻译成本地的机器码后才能执行,而java虚拟机的翻译过程则是解释性的。
#java的JDK提供了两个命令"javac"和"java"分别用于执行编译和解释的过程。
"javac"命令可以将.java文件编译成.class文件,
"java"命令可以通过java虚拟机运行.class文件,并在运行过程中解释成机器语言代码然后执行。
C#语言是编译型语言,但其“编译”过程比较特殊,具体说明如下:
C#程序在第一次运行的时候,会依赖其.NET Frameworker平台,编译成IL中间码),然后由JIT compiler翻译成本地的机器码执行。从第二次在运行相同的程序,则不需要再执行以上编译和翻译过程,而是直接运行第一次翻译成的机器码。所以对于C#来说,通常第一次运行时间会很长,但从第二次开始,程序的执行时间会快很多。
那么,C#为什么要进行两次“编译”呢?其实,微软想通过动态编译(由JIT compiler工具实现)来实现其程序运行的最优化。如果代码在运行前进行动态编译运行,那么JIT compiler可以很智能的根据你本地机器的硬件条件来进行优化,比如使用更好的register,机器指令等等,而不是像原来那样,build一份程序针对所有硬件的机器跑,没有充分利用各个机器的条件。
另外,还有我们经常用到的脚本语言,比如JavaScript、Shell等语言都是脚本语言,本质上来说,脚本语言就是解释型语言。
问题:既然java源代码也是可以跨平台解释执行的,那为什么还需要编译成字节码执行呢?
字节码解析速度更快
字节码size压缩的更小
字节码格式版本更稳定,语法改变大部分情况下不影响字节码格式
字节码可以在编译时提前做编译优化,节省运行时编译优化时间
字节码能保护源码,增加反编译成本
字节码能支持多语言,在其平台上开发新语言更容易
编译器前端和虚拟机可以独立开发,互不影响。有中间格式也更容易debug