编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China 头条阅读 学淘股 China Travel
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> Java -> JavaSe: String的编译期优化 -> 正文阅读

[Java]JavaSe: String的编译期优化

Java的编译期优化
因为工作的原因,经常会在没有源码的情况下,对一些产品的代码进行阅读。有时在解决Bug时,在运行环境下会直接去看class文件的字节码,来确定运行中版本是否正确的。
在看字节码时,发现了一个有意思的现象:即便你在代码中使用了定义的常量,反编译后的代码仍会是字符串的字面量。
这个其实就是Java编译器在编译时做了优化,下面就用一个例子来说明一下:

public class StringTest {
    public static final String a1="a";
    public static String a2="a";
    public static void main(String[] args) {
        String a = "a";
        final String b = "b";
        final String c = a + b;
        String d = a + b;
        String e = a + "b";
        String f = "a" + b;
        String g = "a" + "b";
        String h = "ab";
        String i = new String(h);
        String j = a1+b;
        String k = a2+b;

        System.out.println(c == h); // false
        System.out.println(d == h); // false
        System.out.println(e == h); // false
        System.out.println(f == h); // true
        System.out.println(g == h); // true
        System.out.println(i == h); // false
        System.out.println(j == h); // true
        System.out.println(k == h); // false
        
        // 字面量,final 都会在编译期被优化,并且会被直接运算好
        // 所以 f,g,j 在编译期就直接变为"ab"
        // 因为a,a2是变量, 所以使用到a,a2的表达式,都是在运行时才去计算的
    }
}

 使用 javap命令查看字节码如下:
结合localvariabletable,分析main执行的过程如下:
 

从这里面,可以很明显的看到 运行时加载到f,g,h,j 时,直接就是字面量“ab”。
java中的==的作用是值的比较:
1)对于boolean,int,char,short,double,float,byte,long 这8种基本类型的比较,是比较值是否相等。
2)对于对象的比较,是比较地址的。
 字符串字面量,和用final 修饰的 boolean,int,char,short,double,float,byte,long的变量一样,被统称为常量,它们是存在于常量池中的。
常量池中的内容只保留一份。上面例子中的f,g,j,h都是常量,它们的地址是同一个。所以比较的结果就是true。
而其它的,都是在运行时计算出来的,他们是在heap内存区域的(与常量池不在同一区域),所以他们的地址也就不一样了。所以比较的结果就是false了。
同理,对于其它的 boolean,int,char,short,double,float,byte,long常量 ,也会在编译期进行优化的。
  Java 最新文章
初入山门,需记门规
java 操作本地数据库 mysql
spring boot 整合 mybatis
单表(SSM、SpringBoot、SpringCloud、Free
Mybatis框架中Mapper动态代理方式
IDEA报错:Error starting ApplicationCont
JDK源码之String、StringBuffer、StringBui
java 初始化与清理
Java 对象初始化
第四天知识点
上一篇文章      下一篇文章      查看所有文章
加:2017-12-09 23:27:29  更:2017-12-09 23:27:41 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 头条阅读 学淘股 China Travel 日历 万年历 2020年4日历
2020-4-8 20:13:17
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识