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指令.本文讲解了常见的这些指令的作用 ...
随机推荐
- 【事件中心 Azure Event Hub】Event Hub Java SDK的消费端出现不消费某一个分区中数据的情况,出现IdleTimerExpired错误消息记录
问题情形 使用Java SDK编写的Event Hub消费端应用,随机性遇见了某个分区没有消费消息的情况,在检查日志时候,有发现IdelTimeExpired的错误记录.在重启应用后,连接EventH ...
- java 保留小数点后指定位数四种方法
1 package com.itheima_01; 2 3 import java.math.BigDecimal; 4 import java.text.DecimalFormat; 5 impor ...
- Microsoft.Extensions.DependencyInjection中的Transient依赖注入关系,使用不当会造成内存泄漏
Microsoft.Extensions.DependencyInjection中(下面简称DI)的Transient依赖注入关系,表示每次DI获取一个全新的注入对象.但是使用Transient依赖注 ...
- Lambda表达式(一)
Lambda表达式其实就是实现SAM接口的语法糖,作用就是简化代码的冗余,同时可读性也好过匿名内部类. 以下先一步步演示是如何把大段的代码变成一句代码的,加强理解! 第一种正常的写法 1 public ...
- dd 在度娘上看到的一个大牛的《背包九讲》 (:
P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...
- Cocos2d-x extensions库使用问题解决方法
需要在加入头文件#include "cocos-ext.h" 1>e:\cocos\cocos2d-x\cocos2d-x-3.10\extensions\gui\cccon ...
- 关于cookie与本地 存储的区别的问题。
关于cookie与本地 存储的区别的问题. 1. cookie在浏览器和服务器间来回传递.而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存. 2. coo ...
- 重要,知识点:InnoDB的插入缓冲
世界上最快的捷径,就是脚踏实地,本文已收录[架构技术专栏]关注这个喜欢分享的地方. InnoDB引擎有几个重点特性,为其带来了更好的性能和可靠性: 插入缓冲(Insert Buffer) 两次写(Do ...
- elk部署(实操二)
续上篇 https://www.cnblogs.com/wangql/p/13373022.html 安装logstash 下载地址:wget https://artifacts.elastic.c ...
- shell脚本之整数二次元比较操作符
1.常用二次元比较操作符知识 我们也可以通过man test查看 提示: (1) ">"和"<"符号,在单括中需要转义,在双中括号中不需要转义,因为 ...