从jvm编译优化角度解读String的赋值比较
来源:互联网 发布:开源的数据库管理工具 编辑:程序博客网 时间:2024/05/22 03:44
JVM工作流程,先JAVAC编译java源文件为class字节码文件,class本身也是描述不同java对象的格式的一种对象。java的class文件是统一的,是基于字节码的,它就是描述程序要运行的虚指令的集合,而这个虚指令的集合与任何平台无关,JVM认识他,在运行时环境(JRE),jvm里将他翻译成对应平台OS指令。进程启动时,通常会加载一些JVM核心库,并不会加载项目中所有CLASS,程序访问类之前,需要先用jvm的classloader预加载,同一个classloader中一个类原则上只会被加载一次,在常见的web容器中(如Tomcat)加载不同deploy(部署工程)会相互隔离,使用不同的classloader来加载不同的deploy,也就是并非真正意义上的隔离,跨classloader访问还是可以做到的
下面是String对象赋值比较的例子:
public class StringTest { static String a = "a"; static String b = "b"; static final String c = "a"; static String d = "a"+"b"; static String e = a+"b"; static String f = c+"b" ; static String g = getA()+"b"; static String h = new String(d); public static String getA(){ return "a"; } /** * jvm编译时优化原理,jvm有常量池,常量计算在编译时就已经获得结果,如"a"+"b"编译后字节码中只有“ab”常量,运行时直接赋值,方法中的返回值不能确定,new String(“ab”)新建对象也是运行时决定,也当作变量,final修饰的对象, * 引用只能被赋值一次,如果编译时不能确定赋值的内容,也当作变量,变量会在运行时新建对象赋值。 * java的基本类型比较,因为编译器的优化原理,编译时,节省常量池空间,编译时能确定的相同常量只用一个引用地址,所以基本类型和其他常量的比较用==比较引用地址。 * intern()是在常量池中用equals()遍历查找值和比较对象相等的引用地址返回,没有就创建一个等值字符串。所以一定会返回相同的引用 * String的equals()方法是重写Object的,在object中是直接用“==”的比较的,String的源码,先用==比较地址引用是否相等,在比较字符串长度,然后逐个字符(charA[i]==charB[i])比较。 * String赋值 用“+”不一定比StringBuffer.append()慢,因为常量相加在编译时就计算好结果了,而append()需要在运行时计算。 */ public static void main(String[] args) { System.out.println(d==e);//false System.out.println(d==f);//true System.out.println(d==g);//false System.out.println(d==h);//false System.out.println(d==g.intern());//true }}
== 在java中是引用地址的比较,java编译器在编译时会将包括基本数据在内的常量,放在常量池中,所有常量对象引用相同的地址,常量的计算也会在编译时完成。方法中的返回值如new String(“ab”),或者return "a";编译时没有做优化,因为方法体优化情况复杂,可能需要递归遍历才知道返回的是什么,即使返回的是常量,也是对常量的引用实现一份拷贝返回的,这份拷贝并不是final的。
i=i++的原理和String赋值时对象的创建个数
public class SelfAdd { /** * i++是先操作,再自加,++i是先自加再操作 * 但是c=c++,在JVM中是做了类似(int temp = c;c++; c=temp)的操作,temp不是真实存在的变量,是栈(后进先出)顶的数据拷贝 * 最终得出c的值为1; */ public static void main(String[] args) { int a=1,b=1,c=1,d=1; a++; ++b; c=c++;//先赋值,再自加,应该是为2了,最终却还是等于一,自加没有成功 d=++d; System.out.println(a+","+b+","+c+","+d);//结果2,2,1,2 String a1="a"+"b";//创建一个对象 String a2=new String("多大的");//创建两个个对象 String str1 = "aaa"; //创建一个对象 String str2 = "bbb"; String str3 = "aaabbb"; String str4 = "aaa" + "bbb";//不会产生新的字符串对象 System.out.println(str3 == str4);//true str4 = str1 + "bbb";//会产生新的字符串对象 System.out.println(str3 == str4);//false str4 = str1 + str2;//会产生新的字符串对象 System.out.println(str3 == str4);//false }}
2 0
- 从jvm编译优化角度解读String的赋值比较
- 从JVM的角度分析String对象的创建
- 从 JVM 的角度解析 String 的不可变特性
- 从JVM的角度看JAVA代码--代码优化
- Java面试——从JVM角度比较equals和==的区别
- Java面试——从JVM角度比较equals和==的区别
- String赋值的方式比较
- 编辑从字节码和 JVM 的角度解析 Java 核心类 String 的不可变特性
- 从代码角度进行优化的技巧
- java中两种不同的 string赋值比较
- 从数学的角度解读react组件的点击事件
- JVM角度比较==和equals的区别·
- 从JVM角度理解线程
- 从jvm的角度来看java的多线程
- 从jvm的角度来看java的多线程
- 从jvm的角度来看java的多线程
- 从jvm的角度来看java的多线程
- 从jvm的角度来看java的多线程
- Mavlink地面站编写之二--Mission Planner编译
- 用TextView实现button点击效果
- 实现简单的输入编辑,录入正确的字符串,出现‘$’,表示撤销前一个输入,发现连续的‘$’,表示连续撤销前面的输入;发现‘%’,表示放弃前面所有录入;生成最终结果。
- margin和padding的区别
- android开发游记:meterial design 5.0 新增控件介绍及使用方法
- 从jvm编译优化角度解读String的赋值比较
- 让你的web应用更安全
- 无源码动态调试APK
- HelloCSDN
- 解释器模式
- Spring 生产者/消费者 使用
- dom加载和js执行的时间先后
- struts2 文件超出大小限制后报404错误
- lua手工编译遇到的问题