对openjdk的javac编译器扩展了一个语法糖
我的扩展功能描述如下:
在java的现有语法中加入var来声明变量,并且可以根据初始化数据来自动类型推导。
举两个例子:
例一:
如下JAVA代码(注意这里的var是新语法):
import java.util.*; public class TestHello { private var i = new ArrayList<List<?>>(); }
在用我修改的编译器编译之后,再用反编译工具反编译之后会看到如下形式的代码:
import java.util.ArrayList;
import java.util.List; public class TestHello
{
private ArrayList<List<?>> i = new ArrayList();
}
例二:
如下JAVA代码(注意这里的var是新语法):
public class TestInit {
public var v = 1.0;
}
在用我修改的编译器编译之后,再用反编译工具反编译之后会看到如下形式的代码:
public class TestInit
{
public double v = 1.0D;
}
思路本身非常简单:
1.用初始化语句右表达式的类型做为变量的类型。
2.如果没有初始化值,或为空,则无法推导,这时就直接用Object。
不过:
因为我刚刚对javac的源代码研究了一天,仅仅是大致看了“词法分析”和“语法分析”的代码,所以我做这个语法扩展是在语法分析的过程中加的代码,这样的做法是有局限性的,即:只有当初始化表达式中存在常量,或用new操作符后面有声明类型的情况下才可以自动类型识别,而不能对于用函数调用(或属性引用)来初始化变量的情况进行识别(这是因为在语法分析过程中,分析到这个变量初始化的语句时,通常还没有分析到依赖的其它资源呢),所以如果要做得全面一些,则不能在语法分析过程进行类型识别,而是要在整个语法分析完成之后再第二次扫描语法树,这样就可以做到了。
暂时不打算再继续完善这个扩展了,以后如果实现自己的语言编译器再考虑完整的类型识别系统实现。
我的代码可以在这里下载:https://github.com/naturemickey/valjavac
下载后在代码中搜“ADD BY ZHOUYOU”就可以找到我写的代码(只有几十行而已),其它的代码都是openjdk的。
注意:我是用jdk8u40的javac代码来修改的,所以读者如果要自己实践的话,需要安装jdk8(java编译器是bootstrap的,完全用java编写的)。
由于很多人对javac的代码不熟(其实我也只是刚刚接触第二天而已,也不熟),所以再多提一句:
openjdk的javac运行的主类是com.sun.tools.javac.Main,直接运行这个类,并把要编译的文件名做为main函数的参数即可。
对openjdk的javac编译器扩展了一个语法糖的更多相关文章
- 早期(编译器)优化--Java语法糖的味道
1.泛型与类型擦除 泛型的本质是参数化类型的应用,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口和泛型方法.在泛型没有出现之前,只能通过 ...
- JVM总结-Java语法糖与Java编译器
自动装箱与自动拆箱 首先要提到的便是 Java 的自动装箱(auto-boxing)和自动拆箱(auto-unboxing). 我们知道,Java 语言拥有 8 个基本类型,每个基本类型都有对应的包装 ...
- 第一章-Javac编译器介绍
1.Javac概述 编译器可以将编程语言的代码转换为其他形式,如Javac,将Java语言转换为虚拟机能够识别的.class文件形式.而这种将java源代码(以.java做为文件存储格式)转换为cla ...
- java-关于java_home配置,classpath配置和javac,java命令,javac编译器,和java虚拟机之间的关系
在每个人学习java的第一步,都是安装jdk ,jre,配置java_home,classpath,path. 为什么要做这些?在阅读java-core的时候,看到了原理,p141. 一 关于类的共享 ...
- 早期(编译器)优化--javac编译器
java语言的“编译期”其实是一段“不确定”的操作过程,可能是指一个前端编译器把.java变成.class的过程,也可能是指虚拟机的后端运行期编译器(JLT)把字节码转变成机器码的过程,也有可能是使用 ...
- 笔记:Javac编译器
Javac编译器是把 *.java 文件转换为 *.class 文件,是一个前端编译器:对应着有一种把字节码转变为机器码的编译器,称为JIT编译器(Just In Time Compiler),比如 ...
- Javac编译器详解
学习<深入了解Java虚拟机>有一段时间了,大概理解了Java从源代码编译到执行出结果的过程,也能明确的知道Java是半解释性语言.在执行源代码时,先通过Javac编译器对源代码进行词法分 ...
- 早期javac编译器优化
学习<深入了解Java虚拟机>有一段时间了,大概理解了Java从源代码编译到执行出结果的过程,也能明确的知道Java是半解释性语言.在执行源代码时,先通过Javac编译器对源代码进行词法分 ...
- Javac 编译器
编译过程 Javac 编译过程大致可以分为1个准备过程和3个处理过程: 准备过程:初始化插入式注解处理器. 解析与填充符号表过程,包括: 词法.语法分析,将源代码的字符流转变为标记集合,构造出抽象语法 ...
随机推荐
- 设置清除html5页面缓存
设置清除html5页面缓存 html5端设置 meta 标签: <meta http-equiv="Pragma" content="no-cache" ...
- Linux下高并发socket最大连接数所受的各种限制(详解)
1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每 ...
- bzoj2823: [AHOI2012]信号塔&&1336: [Balkan2002]Alien最小圆覆盖&&1337: 最小圆覆盖
首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面, ...
- UVA - 11488 Hyper Prefix Sets(trie树)
1.给n个只含0.1的串,求出这些串中前缀的最大和. 例1: 0000 0001 10101 010 结果:6(第1.2串共有000,3+3=6) 例2: 01010010101010101010 1 ...
- I.MX6 DNS 查看、修改方法
/************************************************************************** * I.MX6 DNS 查看.修改方法 * 说明 ...
- 实现的是Linux和Windows之间的一种共享--samba
samba 基本配置及自定义控制 https://www.cnblogs.com/l-hh/p/9473937.html Samba简介: Samba实现的是Linux和Windows之间的一种共享, ...
- DP专题之概率DP
注意:在概率DP中求期望要逆着推,求概率要正着推 概率DP求期望: 链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 dp[ i ]表示从i点走到n ...
- 关于netty的多个handler链式模式
1. 老规矩, 引入我们喜闻乐见的maven依赖 <dependency> <groupId>io.netty</groupId> <artifactId&g ...
- linux简单技巧和怎么样进入root用户
1.使用shell的Tab键自动补全 Tab在linux命令行输入中可以自动完成.在linux 命令行中使用Tab键会极大提高输入效率2.使用shell的历史记录 shell会记录用户执行命令的历史记 ...
- Javaweb的9大内置对象
request(请求) response(响应) session(一个用户存放数据,安全) application(一个项目一般有一个,多用户共享存简单数据) out(输出,在页面输出内容) conf ...