想了解javac吗?想了解javac和java命令详解教程,浅入浅出Javac编译原理?? 吗?......本文带你一探究竟。
相信大家在学习java编程的时候,一定使用过javac和java这两个命令。大家在安装JDK的时候,验证是否安装成功,都会在命令行里输入java和javac命令来验证,这就是我们第一次使用java和javac命令。安装成功后,紧接着,我们会写个程序开始我们的java编程之旅。程序写完后,我们需要使用javac命令将源代码编译成class字节码文件,最后,再使用java命令来运行我们的字节码文件。到了这一步,我们的java之旅就正式开始了。一:简单的命令我们先从javac命令开始,javac命令是将源代码编程成class字节码文件,因为我们的JVM虚拟机是执行class字节码文件的,不是执行源代码,JVM虚拟机是不认识源代码的。public class { public static void main(String[] args) { System.out.println("hello world"); } }上面是一段简单的java源代码,我们需要使用javac命令将其编程成字节码文件,才能运行,如下图:执行之后,当前目录下会多出一个.class文件,这就是字节码文件,如下图:如果想运行,那么可以使用java命令来执行class字节码文件:执行结束后,在控制台,输出hello world字符串。另外,需要注意,并不是每个字节码都能得到执行,只有含有main方法的class文件才能执行,因为,main方法是java程序的入口。二:复杂的命令当我们的java源文件有包结构的时候,再使用javac命令编译,就需要一些参数。举个例子,我有两个类,一个是Dog类,一个是Test测试类:package com.dayuanit.animal; public class Dog { public void move() { System.out.println("dog move"); } }package com.dayuanit.test; import com.dayuanit.animal.Dog; public class Test { public static void main(String[] args) { Dog dog = new Dog(); dog.move(); } }这两个类,使用javac命令编译如下:我来解释下上面的命令,这个javac编译比之前的多了一个“-d”参数,这个参数是用来生成包结构的,也就是源代码声明的package目录结构,我们需要将生成的class字节码文件放在这个package下面,通过javac命令,能够帮助我们自动生成package目录,并且能够将class字节码文件放在对应目录的下面,很方便吧:编译过之后,会在当前目录下生成包目录,如上图,另外,注意,"-d"参数后面有个".",这个点代表当前目录,当然你也可以改为其他目录。源代码已经编译好了,那么我们该如果运行呢?如上图,我们使用java命令直接运行Test,发现报错了。因为此时Test有了包结构,它的全名称应该叫:com.dayuanit.test.Test,所以,我们的命令应该是:如上图,我们就能够正确运行Test类了,这里强调一下,当类有了包名后,类的名字就是包名+类名了,这才是它的真实名称。三:把编译后的字节码放在其他位置。我们知道javac命令的-d参数能够帮助我们生成包目录结构,另外,还能指定生成包目录放在哪里,好,我们来看下如何使用。如上图,-d参数后面我跟上 e:/,这代表我将编译后的包目录放在了e盘下面了:好,我们将字节码放在了e盘,如何运行字节码呢?方法有两个,且看第一种方式:我们可以到E盘下面,然后运行java命令即可,如上图,因为我们的包在E盘下面。第二种方式:如上图,这次我们还是在源代码目录,编译之后,字节码都在E盘下面,但是我们要在源代码目录下直接运行E盘下面的字节码,我们在java命令后面跟上了 -classpath参数,这个参数是告诉java虚拟机,到E盘下面找我们的class字节码文件,当然你也可以指定多个目录,用“;”分号隔开即可。以上,我们分析了如何使用javac和java命令进行代码的编译和运行,有了以上的学习,我相信大家对javac和java命令会有更深刻的理解和认知。
浅入浅出Javac编译原理Java语言是当今程序员中使用最广的语言,不光是从语言本身来说,还包括了与Java相关的一些概念。例如JDK,J2EE,JVM等等。还不断有新的语言出现,如groove,scale等,他们到底和Java有什么关系,为什么这些非Java语言也能够运行在JVM上?Java又和JVM有什么关系呢? 今天这篇文章就是来探索这个问题的,Java语言有Java语言规范,而Java虚拟机也有Java虚拟机规范。二者都有自己的词法和语法解析规则,那么如何才能让Java的语法规则适应Java虚拟机的语法规则呢?这个任务就是由Javac编译器来实现的,他的任务就是将Java语言规范转化为Java虚拟机语言规范,将Java的源代码转化为class字节码。小编认为,掌握任何一门语言的前提都是要明白语言底层的编译机制,所以我们爪哇岛的第一篇文章就从Javac的编译原理开始! 目录 浅入浅出Javac编译原理1.Javac是什么?2.Javac编译器的基本结构3.设计模式之访问者模式3.1访问者模式基本介绍3.2访问者模式实现表示电脑元素的接口————.java创建实现上述接口的实现类———Keyboard.java Monitor.java和Mouse.java定义一个表示访问者的接口 ——— .java创建实现了上述接口的实体访问者———.java使用Main函数来显示Computer的组成部分执行程序,输出结果3.3 Javac中访问者模式的实现1.Javac是什么?Javac是一种编译器,能够将一种语言规范转化为另外一种语言规范。 - 对于C,C++,汇编语言等语言采用的是一边编译一边执行的方式。这些语言可以将源码直接编译为CPU可以识别的目标机器码,因此执行时占用资源较少而且编译速度较快。编译器在这里的功能就是将语言规范转化为机器码规范。 - 对于Java语言来说,由于引入了Java虚拟机,不能够将源码直接编译为CPU可以识别的机器码,因此采用的是完全编译之后才能执行,所以占用的时间和空间都比较大。编译器(Javac)在这里的功能就是将Java源代码转化为Java虚拟机所能够识别的JVM语言,Java虚拟机再进一步将JVM语言编译为CPU可以识别的目标机器码。2.Javac编译器的基本结构想要搞清楚Javac编译器的基本结构,那么首先就要明白一个编译器将一种语言规范转化为另外一个语言规范需要经过哪些步骤?这就要想起时编译原理这门课的知识了。 首先,要读取源码,一个字节一个字节的都进来,找出字节中有哪些是我们定义的语法关键词,如Java中的If ,while ,for等词语,还要识别哪些关键字是合法的哪些不是,这个步骤就是词法分析过程。词法分析的结果就是形成一个符合Java规范的Token流,就像是在日常和朋友交流中,朋友告诉你一句话,你要能分辨出哪些是标点符号,哪些是主语,哪些是谓语等等。 接下来就是要对这些token流进行语法分析了,这一步就是检查这些关键词在一起是不是符合Java语法规范,比如If关键词后边跟的是不是布尔表达式。就像人类语言当中是不是有主谓宾,主谓宾的结合是不是正确,比如吃这个关键词后边就不能跟”屎“这个词语。语法分析的结果是形成一个符合Java规范的抽象语法树。抽象语法树是一个结构化的语法表达形式,它的作用是把语言的主要词法用一个结构化的形式组织在一起,对于这棵语法树我们可以在后面按照新的规则再重新组织,这也是编译器非常重要的功能之一。 第三步是语义分析,语义分析是把一些难懂的复杂的语法转化为更加简单的易于编译器理解的语法,例如将for each转化为for循环结构,解释注解等等。这个步骤对应到人类语言中类似于将文言文转化为大家都能懂的白话文。语义分析的结果是形成一个新的抽象语法树,这个语法树更加接近JVM语言的语法规则。 最后一步,通过字节码生成器根据新的抽象语法树生成字节码,也就是将一个数据结构(抽象语法树)转化为另一个数据结构(字节码)。就像所有的中文词语翻译成英文单词之后,按照英文语法组装成英文语句。 代码生成器的结果就是生成符合Java虚拟机规范的字节码了。这个过程需要的组件可以参照下图。 Javac组件 Javac的各个模块完成了将Java源代码转化成JVM字节码的任务。Javac主要有四个模块,分别是词法分析器,语法分析器,语义分析器和代码生成器。3.设计模式之访问者模式前面介绍的词法分析器、语法分析器、语义分析器和代码生成器中有多次遍历语法树的过程,然而每次遍历这棵语法树都会进行不同的处理动作,对这棵语法树也要进行进一步的处理。这是如何实现的呢?这实际上就是采用了访问者模式设计的,每次遍历都是一次访问者的执行过程。3.1访问者模式基本介绍在访问者模式中,我们使用了一个访问者类,目的是将数据结构与数据操作相分离,降低稳定的数据结构和易变的数据操作之间的耦合性。在被访问的类里面加一个和对外提供接待访问者的接口,将自身引用传入访问者。 优点:符合单一职责原则;优秀的扩展性,可以方便满足不同的访问需求;访问条件的灵活性, 缺点:具体元素对访问者公布细节,违反了迪米特原则;具体元素变更比较困难,需重写相应的接口;违反了依赖倒置原则,没有依赖抽象,依赖了具体类! 建议使用场景:对象结构中类很少改变,但是需要经常在对象结构上定义新的操作;需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作”污染“这些对象。3.2访问者模式实现 访问者模式实现UML图 表示电脑元素的接口————. interface { public void accept( ); }创建实现上述接口的实现类———Keyboard.java Monitor.java和Mouse. class Keyboard { @Override public void accept( ) { //暴漏了this,使得该类可以被visit .visit(this); } } public class Monitor { @Override public void accept( ) { .visit(this); } } public class Mouse { @Override public void accept( ) { .visit(this); } }定义一个表示访问者的接口 ——— . interface { public void visit(Mouse mouse); public void visit(Keyboard keyboard); public void visit(Monitor monitor); }创建实现了上述接口的实体访问者———. class { @Override public void visit(Mouse mouse) { //add some codes to consume the elements of Class mouse System.out.println(" Mouse."); } @Override public void visit(Keyboard keyboard) { //add some codes to consume the elements of Class keyboard System.out.println(" Keyboard."); } @Override public void visit(Monitor monitor) { //add some codes to consume the elements of Class monitor System.out.println(" Monitor."); } }使用Main函数来显示Computer的组成部分public class { public static void main(String[] args) { computer = new Computer(); computer.accept(new ()); } }执行程序,输出结果 Mouse. Keyboard. Monitor.访问者模式中一般有抽象访问者、具体访问者、抽象节点元素、具体节点元素、结构对象和客户端几种角色,它们的具体左右如下所述。抽象访问者():声明所有访问者需要的接口.具体访问者():实现抽象访问者声明的接口。抽象节点元素():提供一个接口,能够接受访问者作为参数传递给节点元素。具体节点元素(Keyboard,Mouse和Monitor):实现抽象节点元素声明的接口。结构对象(本样例中没有):提供一个接口,能够访问到所有的节点元素,一般作为一个集合特有节点元素的引用。客户端():创建节点元素的对象,调用访问者访问节点元素。3.3 Javac中访问者模式的实现访问者模式可以将数据结构和对数据结构的操作解耦,使得增加对数据结构的操作不需要去修改数据结构,也不必去修改原有的操作,而是在执行时再定义新的具体访问者(visitor)就行了。在Javac中,不同的编译阶段都定义了不同的访问者模式实现。Javac就是基于访问者模式来遍历语法树的,在编译的不同阶段(词法分析,语法分析,语义分析,字节码生成器)定义不同的访问者从而实现在不需要修改原有语法树的数据结构的前提下,多次访问语法树参考教程: 菜鸟教程——访问者模式 许令波——深入分析Java Web技术内幕(第四章)
上述文章了解到关于javac和java命令详解教程,浅入浅出Javac编译原理?? ,让我们对javac 有一个直观的认知。我们发现,作为一个优秀的Java程序员是多么的自豪。
只要一个电话
我们免费为您回电