第10章, 早期(编译期)优化
2017-08-26 15:05
183 查看
1、概述:
编译过程的编译器:1、前端编译器:Sun的Javac、Eclipse JDT中的增量式编译器(ECJ) (.java文件变为*.class过程)
2、JIT编译器:HotSpot VM 的C1、C2编译器(.class文件变成机器码的过程)
3、AOT编译器:GNU Compiler for the java(GCJ)、Excelsior JET(.java文件直接变成机器码的过程)
2、Javac编译器
编译器过程大致分为三个过程1、解析与填充符号表过程
2、插入式注解处理器的注解处理过程
3、分析与字节码生成过程
2.1 解析与填充符号表
1、词法、语法分析2、填充符号表
总结:不恰当比喻---将不同大小苹果先检出来,按照放入不同筐内。
2.2 注解处理器
注解与普通代码类似,根据不同注解重复修改语法树。(塑像进行雕刻,而注解是刀,塑像是语法树)2.3 语义分析与字节码生成
表示代码正确,还要符合类型之间关系int a=1;
boolean b = false;
char c = 2;
int d = a+c (编译正确)
int d = b+c(编译异常)
1、标注检查
常量折叠:例如 int a= 1+2; 代表是 int a =3
2、数据及控制流分析
3、解语法糖
定义:增加程序可读性,对功能没有的影响的语法
4、字节码生成
3、java语法糖的味道
3.1、泛型与类型擦除
真实泛型:就是泛型一直存在到运行期,List<int>与List<String>就是不同类型,它们有自己的虚方法表和类型数据。伪泛型:java语言的泛型,它只存在于源码中,后期编译会替换原来的原生类型,并且在相应位置插入强制转换代码,这就是java类型擦除
package com.jack;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Throwable{
Map<String, String> map = new HashMap<String,String>();
map.put("hello", "你好");
map.put("how are you?", "点点滴滴");
System.out.printf(map.get("hello"));
System.out.printf(map.get("how are you?"));
}
}
编译成字节码文件后反编译为:
package com.jack;
import java.util.HashMap;
public class Main {
public static void main(String[] arg) throws Throwable {
HashMap arg0 = new HashMap();
arg0.put("hello", "你好");
arg0.put("how are you?", "点点滴滴");
System.out.printf((String) arg0.get("hello"), new Object[0]);
System.out.printf((String) arg0.get("how are you?"), new Object[0]);
}
}List<Integer> 和List<String>代表同一个类
import java.util.List;
public class GenericTypes {
public static void method(List<String> list) {
System.out.printf("invoke method(List<String> list)");
}
public static void method(List<Integer> list) {
System.out.printf("invoke method(List<Integer> list)");
}
}会出现编译错误 :Erasure of method method(List<Integer>) is the same as another method in type (表示擦拭泛型后代表相同类)
3.3 自动装箱、拆箱与遍历循环
import java.util.Arrays;import java.util.List;
public class Main {
public static void main(String[] args) throws Throwable{
List<Integer> list = Arrays.asList(1,2,3,4);
int sum =0;
for (int i: list){
sum +=i;
}
System.out.println(sum);
}
}
编译后的代码
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] arg) throws Throwable {
List arg0 = Arrays
.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
int arg1 = 0;
int arg3;
for (Iterator arg2 = arg0.iterator(); arg2.hasNext(); arg1 += arg3) {
arg3 = ((Integer) arg2.next()).intValue();
}
System.out.println(arg1);
}
}
以上一共包含泛型、自动装箱、自动拆箱、遍历循环与变长参数的五种语法糖
public class Main {
public static void main(String[] args) throws Throwable{
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 222;
Integer f = 222;
Long g = 3L;
System.out.printf("c==d : %s\n", c==d);
System.out.printf("e==f : %s\n", e==f);
System.out.printf("e.equals(f) : %s\n",e.equals(f));
System.out.printf("c == (a+b) : %s\n", c==(a+b));
System.out.printf("c.equals(a+b): %s\n", c.equals(a+b));
System.out.printf("g == (a + b): %s\n", g == (a + b));
System.out.printf("g.equals(a+b): %s\n", g.equals(a+b));
}
}
字节码反编译:
public class Main {
public static void main(String[] arg) throws Throwable {
Integer arg0 = Integer.valueOf(1);
Integer arg1 = Integer.valueOf(2);
Integer arg2 = Integer.valueOf(3);
Integer arg3 = Integer.valueOf(3);
Integer arg4 = Integer.valueOf(222);
Integer arg5 = Integer.valueOf(222);
Long arg6 = Long.valueOf(3L);
System.out.printf("c==d : %s\n", new Object[]{Boolean.valueOf(arg2 == arg3)});
System.out.printf("e==f : %s\n", new Object[]{Boolean.valueOf(arg4 == arg5)});
System.out.printf("e.equals(f) : %s\n", new Object[]{Boolean.valueOf(arg4.equals(arg5))});
System.out.printf("c == (a+b) : %s\n",
new Object[]{Boolean.valueOf(arg2.intValue() == arg0.intValue() + arg1.intValue())});
System.out.printf("c.equals(a+b): %s\n",
new Object[]{Boolean.valueOf(arg2.equals(Integer.valueOf(arg0.intValue() + arg1.intValue())))});
System.out.printf("g == (a + b): %s\n",
new Object[]{Boolean.valueOf(arg6.longValue() == (long) (arg0.intValue() + arg1.intValue()))});
System.out.printf("g.equals(a+b): %s\n",
new Object[]{Boolean.valueOf(arg6.equals(Integer.valueOf(arg0.intValue() + arg1.intValue())))});
}
日志:
c==d : true
e==f : false
e.equals(f) : true
c == (a+b) : true
c.equals(a+b): true
g == (a + b): true
g.equals(a+b): false
总结:
1、如果是对象还是用equals进行比较保险。
2、无论是Integer,Long的装箱拆箱都是基于【-128,127】范围有效
Integer a = 128;
Integer b =128;
a==b 为false
3.3、条件编译
public class Main {public static void main(String[] args) throws Throwable{
if(true){
System.out.printf("模块一");
} else {
System.out.printf("模块二");
}
}
}
编译后:
public class Main {
public static void main(String[] args) throws Throwable{
System.out.printf("模块一");
}
}
相关文章推荐
- 深入理解jvm十-早期(编译期)优化
- 早期(编译期)优化
- JVM-程序编译与代码早期(编译期)优化
- 早期(编译期)优化
- jvm(10)-早期(编译期)优化
- 深入理解java虚拟机-第十章-早期(编译期)优化
- 早期(编译期)优化
- 深入理解JVM之早期(编译期)优化
- [Java虚拟机读书笔记] 10章 早期(编译期优化)优化
- 深入理解JVM(九)——早期(编译期)优化
- [深入理解Java虚拟机]第十章 程序编译与代码优化-早期(编译期)优化
- 深入理解 Java 虚拟机--早期(编译期)优化
- 程序编译与代码优化-早期(编译期)优化
- 早期(编译期)优化
- 早期(编译期)优化
- jdk源码解析(九)——早期(编译期)优化
- Jvm早期优化(编译期)
- 《深入理解java虚拟机》读书笔记-第10章早期(编译器)优化
- EBO,c++编译器有empty继承优化(编译期)