Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编译语言与解释语言_Java_Python_Compiler Construction_Programming Languages_Interpreter - Fatal编程技术网

Java 编译语言与解释语言

Java 编译语言与解释语言,java,python,compiler-construction,programming-languages,interpreter,Java,Python,Compiler Construction,Programming Languages,Interpreter,我正试图更好地理解这种差异。我在网上找到了很多解释,但它们倾向于抽象的差异,而不是实际的含义 我的大部分编程经验都是使用CPython(动态的,解释的)和Java(静态的,编译的)。但是,我知道还有其他类型的解释和编译语言。除了可以从用编译语言编写的程序中分发可执行文件这一事实之外,每种类型都有哪些优点/缺点?我经常听到人们争辩说解释性语言可以交互使用,但我相信编译语言也可以有交互实现,正确的是,一个澄清,java不是完全静态编译和C++连接的。它被编译成字节码,然后由JVM进行解释。JVM可以

我正试图更好地理解这种差异。我在网上找到了很多解释,但它们倾向于抽象的差异,而不是实际的含义


我的大部分编程经验都是使用CPython(动态的,解释的)和Java(静态的,编译的)。但是,我知道还有其他类型的解释和编译语言。除了可以从用编译语言编写的程序中分发可执行文件这一事实之外,每种类型都有哪些优点/缺点?我经常听到人们争辩说解释性语言可以交互使用,但我相信编译语言也可以有交互实现,正确的是

,一个澄清,java不是完全静态编译和C++连接的。它被编译成字节码,然后由JVM进行解释。JVM可以对本机语言进行实时编译,但不必这样做

更重要的是:我认为交互性是主要的实际区别。由于所有内容都是解释的,所以您可以提取一小段代码,解析并根据环境的当前状态运行它。因此,如果您已经执行了初始化变量的代码,那么您就可以访问该变量,等等。它确实适用于函数样式之类的事情

然而,解释的成本很高,尤其是当您有一个包含大量引用和上下文的大型系统时。根据定义,这是浪费,因为相同的代码可能需要解释和优化两次(尽管大多数运行时都有一些缓存和优化)。尽管如此,您还是要支付运行时成本,并且通常需要一个运行时环境。您也不太可能看到复杂的过程间优化,因为目前它们的性能不够交互式

因此,对于不会有太大变化的大型系统,对于某些语言来说,预编译和预链接所有内容更为合理,尽可能进行所有优化。这最终会产生一个非常精简的运行时,该运行时已经针对目标机器进行了优化

至于生成可执行文件,这与此无关,IMHO。通常可以从编译语言创建可执行文件。但是您也可以从解释语言创建可执行文件,除非解释器和运行时已经打包在可执行文件中,并且对您隐藏。这意味着您通常仍需支付运行时成本(尽管我确信对于某些语言,有一些方法可以将所有内容转换为树可执行文件)


我不同意所有语言都可以互动。某些语言,如C语言,与机器和整个链接结构紧密相连,因此我不确定您是否能够构建一个有意义的完全成熟的交互版本,因为区别在于语言定义本身,所以很难给出实际的答案。可以为每种编译语言构建一个解释器,但不可能为每种解释语言构建一个编译器。这在很大程度上是关于语言的正式定义。所以在大学里没有人喜欢理论信息学的东西。

极端和简单的例子:

  • 编译器将以目标机器的本机可执行文件格式生成二进制可执行文件。此二进制文件包含除系统库之外的所有必需资源;它已准备好运行,无需进一步准备和处理,而且运行起来就像闪电一样,因为代码是目标机器上CPU的本机代码

  • 解释器将在循环中向用户提供一个提示,用户可以在循环中输入语句或代码,当点击
    RUN
    或同等按钮时,解释器将检查、扫描、解析并解释性地执行每一行,直到程序运行到停止点或出现错误。因为每一行都是独立处理的,而且解释器不会从之前看到的那一行中“学到”任何东西,所以每次每一行都需要将人类可读的语言转换为机器指令,所以速度很慢。好的一面是,用户可以通过各种方式检查程序并与之交互:更改变量、更改代码、以跟踪或调试模式运行。。。不管怎样

有了这些,让我来解释一下,生活不再那么简单了。比如说,

  • 许多口译员会预先编译他们收到的代码,这样翻译步骤就不必一次又一次地重复
  • 有些编译器编译的不是特定于CPU的机器指令,而是字节码,一种虚拟机器的人工机器代码。这使得编译后的程序更具可移植性,但在每个目标系统上都需要一个字节码解释器
  • 字节码解释器(我在这里看Java)最近倾向于在执行之前(称为JIT)重新编译为目标部分的CPU获得的字节码。为了节省时间,通常只对经常运行的代码(热点)执行此操作
  • 一些看起来和行为都像解释器的系统(例如Clojure)会立即编译它们获得的任何代码,但允许交互访问程序环境。这基本上就是解释器的便利性和二进制编译的速度
  • 有些编译器并不真正编译,它们只是对代码进行预消化和压缩。我听说Perl就是这样工作的。所以有时候编译器只是做了一点工作,而大部分工作仍然是解释
最后,这些天来,解释与编译是一种折衷,花在编译上的时间(一次)往往会得到更好的运行时性能的回报,但解释性环境提供了更多的交互机会。编译与口译主要是“理解”工作的问题