Javac编译器详解
一、了解一下javac编译的详解过程
(1)词法、语法分析
(2)符号填充表(目前这点知识我不是很理解)
(3)注解处理器
(4)语义分析与字节码生成
a) 标注检查
int a = 1;
boolean b = false;
char c = 2;
int d = a + c;
int d = b + c;
char d = a + c;
b) 数据及控制流分析
c) 语法糖
(4)字节码生成
二、Java语法糖的味道
语法糖虽然不会提供实质性的功能改进,但是它们或能提供效率,或能提升语法的严谨性,或能减少编码出错的机会。但是大量添加和使用“含糖”的语法,容易让程序员产生依赖,无法看清程序代码的真实面目。
(1)泛型与类型擦除
泛型早期在Java语言中没有出现时,只能通过Object是所有类型的父类和类型强制转换两个特点的配合来实现类型转化。例如:在哈希表的存取中,1.5之前使用HashMap的get()方法,返回值就是一个Object对象,由于Java语言里面所有的类型都继承于java.lang.Object,所以Object转型成任何对象都是有可能的。但是因为有无限可能性,许多ClassCastException的风险就会转嫁到程序的运行期间。
泛型重载(编译不通过)
public class GenericType{
public static void method(List<String> list){
System.out.print("invoke method(List<String> list)");
}
public static void method(List<Integer> list){
System.out.print("invoke method(List<Integer> list)");
}
}
编译不通过,泛型在编译阶段进行擦除,变成原生类型List<E>,擦除 动作导致这两种方法的特征签名变得一模一样。
(2)自动装箱、拆箱与遍历循环
源代码:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4);
//如果在JDK 1.7中,还有另外一种语法糖
//能让上面这句话进一步简写成List<Integer> list = [1, 2, 3, 4]
int sum = 0;
for (Integer i : list) {
sum += i;
}
System.out.println(sum);
}
编译后的代码:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(new Integer[]{
Integer.valueOf(1),
Integer.valueOf(2),
Integer.valueOf(3),
Integer.valueOf(4)
});
int sum = 0;
for (Iterator localIterator = list.iterator();localIterator.hasNext();){
int i = ((Integer) localIterator.next()).intValue();
sum += i;
}
System.out.println(sum);
}
装箱:基本类型变为包装类型,例如:Integer n = 1;
拆箱:包装类型变为基本类型,例如:int i = n;
重点:包装类重新赋值会创建新的对象,因为每一个包装类型中value都被final修饰的!例如Integer类中:private final int value;
(3) 条件编译
源代码:
public static void main(String[] args) {
if (true) {
System.out.println("block 1");
} else {
System.out.println("block 2");
}
}
编译后的代码:
public static void main(String[] args) {
System.out.println("block 1");
}
只能使用条件为常量的if语句才能达到上述效果,编译器将会把分支中不成立的代码块消除掉,这一过程在编译阶段完成!
重点理解:在前端编译器中,“优化”手段主要用于提升程序的编码效率,之所以把Javac这类将Java代码转变为字节码的编译器称做“前端编译器”,是因为它只完成了从程序到抽象语法树或中间代码的生成,而在此之后,还有一组内置于虚拟机内部的“后端编译器”完成从字节码生成本地机器码的过程,就是即时编译器或JIT编译器,这个编译器的编译速度及编译结果的优劣,是衡量虚拟机性能一个很重要的指标!
Javac编译器详解的更多相关文章
- javac命令详解(下)
摘自http://blog.csdn.net/hudashi/article/details/7058999 javac命令详解(下) -ver ...
- javac命令详解(上)
摘自http://blog.csdn.net/hudashi/article/details/7058998 javac命令详解(上) ja ...
- JAVAC 命令详解(转)
本文来自:http://www.cnblogs.com/JeffChen/archive/2008/01/16/1041783.html 结构 javac [ options ] [ sourcefi ...
- Linux安装gcc编译器详解
本人使用的是CentOS 6.5 64位系统,由于在安装系统的时候并没有勾选安装gcc编译器,因此需要自行安装gcc编译器. 使用yum安装gcc 对于配备了yum的Linux发行版而言,安装gcc编 ...
- JAVAC 命令详解
转自:http://jeffchen.iteye.com/blog/395671 结构 javac [ options ] [ sourcefiles ] [ @files ] 参数可按任意次序排列. ...
- Linux——CentOS7安装gcc编译器详解
使用yum安装gcc 使用yum命令安装还是非常easy的. yum -y install gcc gcc-c++ kernel-devel //安装gcc.c++编译器以及内核文件 手动安装gcc ...
- 6、javac命令详解
javac [ options ] [ sourcefiles ] [ @files ] 参数可按任意次序排列. options 命令行选项. sourcefiles 一个或多个要编译的源文件(例如 ...
- C++编译器详解(三)函数调用的区别:_cdecl以及_stdcall
1._stdcall是Pascal程序的缺省调用方式,通常用于Win32 API中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上&qu ...
- C++编译器详解(二)常见precompiling 指令介绍
VC++编译器中一些常见precompiling 指令介绍 我们在利用vc6.0 project wizard生成的代码中,经常看到大量的precompiling指令.本文讲解了常见的这些指令的作用 ...
随机推荐
- 华为路由器配置OSPF
OSPF是什么 OSPF(Open Shortest Pass First,开放最短路径优先协议),是一个最常用的内部网管协议,是一个链路状态协议. 使用场景:适用于运营商.政府机构等大型网络中多节点 ...
- 【多次实践】win10+ubuntu18.04lts双系统安装葵花宝典(安装篇)
这个教程诞生的缘由很简单,吃的太饱,硬是要折腾,结果,这一折腾便是20余小时,故写此文,帮助后来者少走弯路! 在本文开始,请先允许我对网上很多类似的教程嗤之以鼻,很成功地让我走了很多的弯路,一些有效简 ...
- 手把手教你如何制作和使用lib和dll
本文的内容经过本人亲自调试,确保可用,实用,测试环境为win10+vs2015+C++ 目录 静态库 什么是静态库? 怎么创建 如何使用 静态库的第一种使用方法 静态库的第二种使用方法 动态链接库 动 ...
- mysql优化篇(基于索引)
在上一篇文章:Mysql索引(一篇就够le) 中介绍了索引的基本使用,分类和原理,也强烈建议先读Mysql索引(一篇就够le),然后继续本文的阅读 我们也知道mysql的优化可以从很多的方面进行,比如 ...
- 爬虫在linux下启动selenium-安装谷歌浏览器和驱动(傻瓜式教程)
一.升级yum(防止不必要的麻烦) yum update -y yum -y groupinstall "Development tools" yum install openss ...
- 刷题不应该刷leecode 应该刷oj
因为leecode有很多题目 表述不清 意义不明 最关键的是 leecode压根不规定输入输出的格式 这个完全不是竞赛的风格 这样会养成很多坏习惯
- 卸载联软UniAccess,删除UniAccess Agent记录
UniAccess 卸载 事情起因: 公司假以安全上网为由,让公司员工安装所谓的"XX上网助手",实则是内嵌了联软的UniAccess监控系统. 有关这个软件的用途就不用多介绍了, ...
- 【django-simpleui】‘simpletags‘ is not a registered tag library报错的解决方法
1:创建 templatetags文件夹 2:创建simpletags.py文件将内容粘贴进去,在下面 3:setting.py添加文件指定: 1 TEMPLATES = [ 2 { 3 'BACK ...
- JVM的艺术—类加载器篇(二)
分享是价值的传递,喜欢就点个赞 引言 今天我们继续来深入的剖析类加载器的内容.上节课我们讲了类加载器的基本内容,没看过的小伙伴请加关注.今天我们继续. 什么是定义类加载器和初始化类加载器? 定义类加载 ...
- Linux系统目录简介
Linux系统目录简介 boot 系统启动 grub(内核加载程序,内核≈操作硬件) 界面 自检程序 bin 系统可执行文件 bash=终端程序 sbin 超级用户的可执行文件 root root家目 ...