当前位置: 首页 > 后端技术 > PHP

JAVA中发生了什么Stringa=-abc-

时间:2023-03-30 02:38:47 PHP

andlastinta=1后续测试代码javacTestCode.javapublicclassTestCode{publicstaticvoidmain(String[]args){//这里写aaaa方便看在字节码Stringaaaa="bbbb";aaaa="cccc";}}反编译javap-v-p-lTestCode(l是小写的L)注:javap是jdk自带的反解析工具。作用是根据类字节码文件,逆向分析当前类对应的代码区(汇编指令)、局部变量表、异常表、代码行偏移映射表、常量池等信息。类文件xxxxx/com/code/baseCode/TestCode.class最后修改时间2021-11-22;大小475字节MD5校验和0a108c035194f620555926cf7d113c8b从“TestCode.java”公共类com.code.baseCode.TestCode次要版本:0主要版本:52标志:ACC_PUBLIC、ACC_SUPER常量池:#1=Methodref#5.#21//java/lang/Object."":()V#2=String#22//bbbb#3=String#23//cccc#4=Class#24//com/code/baseCode/TestCode#5=Class#25//java/lang/Object#6=Utf8#7=Utf8()V#8=Utf8Code#9=Utf8LineNumberTable#10=Utf8LocalVariableTable#11=Utf8this#12=Utf8Lcom/code/基础代码/测试代码;#13=Utf8main#14=Utf8([Ljava/lang/String;)V#15=Utf8args#16=Utf8[Ljava/lang/String;#17=Utf8aaaa#18=Utf8Ljava/lang/String;#19=Utf8SourceFile#20=Utf8TestCode.java#21=NameAndType#6:#7//"":()V#22=Utf8bbbb#23=Utf8cccc#24=Utf8com/code/baseCode/TestCode#25=Utf8java/lang/Object{publiccom.code.baseCode.TestCode();描述符:()Vflags:ACC_PUBLICCode:stack=1,locals=1,args_size=10:aload_01:invokespecial#1//Methodjava/lang/Object."":()V4:returnLineNumberTable:line8:0LocalVariableTable:StartLengthSlotNameSignature050thisLcom/code/baseCode/TestCode;publicstaticvoidmain(java.lang.String[]);描述符:([Ljava/lang/String;)V标志:ACC_PUBLIC,ACC_STATIC代码:stack=1,locals=2,args_size=10:ldc#2//Stringbbbb2:astore_13:ldc#3//Stringcccc5:astore_16:returnLineNumberTable:line11:0line12:3line55:6LocalVariableTable:StartLengthSlotNameSignature070args[Ljava/lang/String;341aaaaLjava/lang/String;}SourceFile:"TestCode.java"反编译后会发现aaaa存在于Constantpool(常量池)和LocalVariableTable(局部变量表)中。discovery和inta=1的区别在于字符串“bbbb”和“cccc”也会在常量池中。JVM中常量池的划分,请看上一篇讲解java1.8内存布局的图片。编译后内存情况会怎样?如何查看Java字节码指令?https://en.wikipedia.org/wiki...http://githuan.com/2015/10/24...其中java字节码为0:ldc#2//Stringbbbb2:astore_13:ldc#3//Stringcccc5:astore_1ldc:从常量池中压入一个常量#index(String,int,float,Class,java.lang.invoke.MethodType,java.lang.invoke.MethodHandle,或者一个动态计算的常量)入栈的意思是:将int,float,String等常量从常量池中压入thestackTopastore_1:storeareferenceintolocalvariable1的意思是:把一个引用放到局部变量1中(也就是在aaaa中)ldc#2astore_1ldc#3astore_1图片说明:用newString()创建,改代码如下:publicclassTestCode{publicstaticvoidmain(String[]args){Stringaaaa=newString("bbbb");aaaa=newString("cccc");}}会在常量池里多找点东西,执行命令太多执行指令如下:new#2//classjava/lang/String3:dup4:ldc#3//Stringbbbb6:invokespecial#4//Methodjava/lang/String."":(Ljava/lang/String;)V9:astore_110:new#2//classjava/lang/String13:dup14:ldc#5//Stringcccc16:invokespecial#4//Methodjava/lang/String."":(ljava/lang/String;)V19:astore_1new:创建一个类实例dup:复制值,并压入栈顶ldc:从常量池压入栈顶invokespecial:调用特殊实例方法(包括实例初始化方法、父类方法)astore_1:一个引用放在局部变量1(也就是aaaa)中。常量池如下Constantpool:#1=Methodref#7.#23//java/lang/Object."":()V#2=Class#24//java/lang/String#3=String#25//bbbb#4=Methodref#2。#26//java/lang/String."":(Ljava/lang/String;)V#5=String#27//cccc#6=类#28//com/code/baseCode/TestCode#7=Class#29//java/lang/Object#8=Utf8#9=Utf8()V#10=Utf8Code#11=Utf8LineNumberTable#12=Utf8LocalVariableTable#13=Utf8this#14=Utf8Lcom/code/baseCode/TestCode;#15=Utf8main#16=Utf8([Ljava/lang/String;)V#17=Utf8args#18=Utf8[Ljava/lang/String;#19=Utf8aaaa#20=Utf8Ljava/lang/String;#21=Utf8SourceFile#22=Utf8TestCode.java#23=NameAndType#8:#9//"":()V#24=Utf8java/lang/String#25=Utf8bbbb#26=NameAndType#8:#30//"":(Ljava/lang/String;)V#27=Utf8cccc#28=Utf8com/code/baseCode/TestCode#29=Utf8java/lang/Object#30=Utf8(Ljava/lang/String;)Vnew#2dupldc#3invokespecial#4astore_1后面的操作都是一样的,所以Stringa=newString("bbbb");Stringb=newString("bbbb");System.out.println(a==b);//false面试题做下面的题是,你需要知道的几个知识点1.编译时,编译器会优化准确的值:比如Stringa="a"+"b";->例如Stringa="ab";最终字符串a="a";字符串b="a"+a;->字符串b="aa";2。添加字符串变量会创建一个StringBuilder并调用append方法,然后将StringBuilder转换成一个新的String3.intern:Java查找常量池中是否有Unicode相同的字符串常量,有则返回如果没有引用,则在常量池中添加Unicode等于str的字符串,并返回其引用字符串s11="a";字符串s22="bc";字符串s1="abc";字符串s2="a"+"bc";字符串s3=new字符串("a")+"bc";字符串s4=newString("a")+newString("bc");Strings5=newString("abc");Strings6=s11+s22;System.out.println(s1==s2);System.out.println(s1==s3);System.out.println(s1==s4);System.out.println(s1==s5);System.out.println(s1==s6);System.out.println(s3==s4);System.out.println(s4==s5);System.out.println(s1==s5.intern());System.out.println(s1==s6.intern());System.out.println(s1.equals(s5));System.out.println(s1.equals(s6));答案解释:https://zhuanlan.zhihu.com/p/...出来之前end是int类型的情况,上面是String类型的情况,后面是封装类型的情况