I学霸官方免费教程十九:Java常用类之String类
来源:互联网 发布:php怎么防止xss攻击 编辑:程序博客网 时间:2024/05/18 01:33
String类
首先,String是引用类型,也是唯一一个可以不使用关键字new创建对象的引用类型,因为有字符串常量值,使用英文格式的双引号""括起来就是字符串常量值。创建对象的两种方式
方式一、String s1 = “abc”;
方式二、String s2 = new String(“abc”);
这两种方式都是创建了一个字符串对象,值都是字符串abc;
不同的是
方式一是直接使用字符串常量abc赋值给变量s1,此时系统先到常量池中查找有没有字符串常量abc,如果有将字符串常量abc在常量池中的地址赋值给变量s1,如果没有会将字符串常量abc加入到常量池中,并把地址赋值给变量s1。
而方式二是在堆内存中创建一个String类型的对象,在这个对象中存储着字符串abc
其次,String类型被设计成不可变的,即对象不可变;一旦对象被创建,这个对象将无法被修改,引用(变量)是可以修改;如上例中s1是引用(变量),它可以存储其他字符串的地址,但是字符串abc本身被创建后无法再改变了。
实例:
//创建一个String类型的对象
String s = "abc";
//如果要将变量s的修改为"abcxyz",代码如下
s = s+"xyz";
//输出结果为:abcxyz
System.out.println(s);
//由于这里使用两个字符串常量相连接,系统会默认当成一个字符串,即"abcxyz"
String s1 = "abc" + "xyz";
String s2 = "abcxyz";
其中第二行代码会先到常量池中查找有没有字符串xyz,如果没有将字符串xyz加入到常量池中,此时常量池中有abc和xyz两个字符串常量;
然后系统底层会默认在堆中创建一个StringBuilder类型的对象;然后用StringBuilder对象的append方法,将两个字符串连接到一起,最后再调用toString方法返回连接后的字符串abcxyz,并将返回的字符串abcxyz的地址赋值给变量s。
接下来验证实例中变量s、s1和s2三个变量,引用的是不是一个对象。可以使用双等号来进行判断。
//输出结果为:false
System.out.println(s == s1);
//输出结果为:true
System.out.println(s1 == s2);
由以上结果可以看出,变量s1和s2中存储的是同一字符串对象的地址,而变量s中存储的是另一字符串对象的地址,但这两个字符串对象的内容是相同的(都是abcxyz);那么如何判断两个字符串的内容是否相同呢?
在String类中已经重写了父类Object中的equals方法,通过equals方法可以判断两个字符串内容是否相同
//输出结果为:true
System.out.println(s.equals(s1));
总结:
当使用字符串常量时,系统会先到常量池中寻找,如果没找到,将字符串常量加入到常量池中。
使用关键字new创建的字符串对象保存在堆内存中。
使用字符串连接符+连接两个字符串常量时,系统会自动将它们当成一个字符串常量,并将其存储在常量池中
使用字符串连接符+字符串变量时,连接后的字符串存储在堆内存中
比较两个字符串的内容是否相同使用equals方法
所有引用类型使用双等号==比较时,比较的是对象地址是否相同,即是否是同一对象
以下内容初学者选读
//类A的源码public class A{String s = "abc" + "d";}
//打开字节码文件的命令:javap -verbose A//以下是类A编译后class文件的内容//关键行#2和5: ldc,可以看到Java编译器是将"abc" + "d"当做"abcd"来处理的Classfile /H:/A.class Last modified 2015-5-29; size 239 bytes MD5 checksum 271095a9d37f742c9bdefa883c6b9a00 Compiled from "A.java"public class A minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #5.#14 // java/lang/Object."<init>":()V #2 = String #15 // abcd #3 = Fieldref #4.#16 // A.s:Ljava/lang/String; #4 = Class #17 // A #5 = Class #18 // java/lang/Object #6 = Utf8 s #7 = Utf8 Ljava/lang/String; #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 SourceFile #13 = Utf8 A.java #14 = NameAndType #8:#9 // "<init>":()V #15 = Utf8 abcd #16 = NameAndType #6:#7 // s:Ljava/lang/String; #17 = Utf8 A #18 = Utf8 java/lang/Object{ java.lang.String s; descriptor: Ljava/lang/String; flags: public A(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: ldc #2 // String abcd 7: putfield #3 // Field s:Ljava/lang/String; 10: return LineNumberTable: line 1: 0 line 2: 4}SourceFile: "A.java"
//类B源码public class B{String s = "abc";String s1 = s+"d";}
//类B的class文件//首先看#2和#7,这里不在是当做一个字符串来处理的了//然后看5: ldc和25: ldc,这两行是将两个字符串常量压栈//11: new,这里创建了一个StringBuilder类的对象//22: invokevirtual和27: invokevirtual调用了StringBuilder对象的append方法,将两个字符串追加到一起//最后30: invokevirtual,调用了StringBuilder对象的toString方法,获得连接后的字符串"abcd"Classfile /H:/B.class Last modified 2015-5-29; size 443 bytes MD5 checksum 3eaa63a1c104ccfe26e2a6f9df85d93c Compiled from "B.java"public class B minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #11.#21 // java/lang/Object."<init>":()V #2 = String #22 // abc #3 = Fieldref #10.#23 // B.s:Ljava/lang/String; #4 = Class #24 // java/lang/StringBuilder #5 = Methodref #4.#21 // java/lang/StringBuilder."<init>":()V #6 = Methodref #4.#25 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #7 = String #26 // d #8 = Methodref #4.#27 // java/lang/StringBuilder.toString:()Ljava/lang/String; #9 = Fieldref #10.#28 // B.s1:Ljava/lang/String; #10 = Class #29 // B #11 = Class #30 // java/lang/Object #12 = Utf8 s #13 = Utf8 Ljava/lang/String; #14 = Utf8 s1 #15 = Utf8 <init> #16 = Utf8 ()V #17 = Utf8 Code #18 = Utf8 LineNumberTable #19 = Utf8 SourceFile #20 = Utf8 B.java #21 = NameAndType #15:#16 // "<init>":()V #22 = Utf8 abc #23 = NameAndType #12:#13 // s:Ljava/lang/String; #24 = Utf8 java/lang/StringBuilder #25 = NameAndType #31:#32 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #26 = Utf8 d #27 = NameAndType #33:#34 // toString:()Ljava/lang/String; #28 = NameAndType #14:#13 // s1:Ljava/lang/String; #29 = Utf8 B #30 = Utf8 java/lang/Object #31 = Utf8 append #32 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #33 = Utf8 toString #34 = Utf8 ()Ljava/lang/String;{ java.lang.String s; descriptor: Ljava/lang/String; flags: java.lang.String s1; descriptor: Ljava/lang/String; flags: public B(); descriptor: ()V flags: ACC_PUBLIC Code: stack=3, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: ldc #2 // String abc 7: putfield #3 // Field s:Ljava/lang/String; 10: aload_0 11: new #4 // class java/lang/StringBuilder 14: dup 15: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 18: aload_0 19: getfield #3 // Field s:Ljava/lang/String; 22: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 25: ldc #7 // String d 27: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 33: putfield #9 // Field s1:Ljava/lang/String; 36: return LineNumberTable: line 1: 0 line 2: 4 line 3: 10}SourceFile: "B.java"
//类C源码public class C{String s = new String("abc");String s1 = s+"d";}
//C.class文件内容//这里主要演示类B中String s = "abc";和类C中String s = new String("abc");的区别//首先5: new 这里创建了一个String对象//然后9: ldc 字符串常量"abc"被压栈//最后11: invokespecial 初始化String对象//而类B只有ldc将常量压栈这一步Classfile /H:/C.class Last modified 2015-5-29; size 506 bytes MD5 checksum 97026d45729fe35e1f470e17e1b5f0e0 Compiled from "C.java"public class C minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #13.#23 // java/lang/Object."<init>":()V #2 = Class #24 // java/lang/String #3 = String #25 // abc #4 = Methodref #2.#26 // java/lang/String."<init>":(Ljava/lang/String;)V #5 = Fieldref #12.#27 // C.s:Ljava/lang/String; #6 = Class #28 // java/lang/StringBuilder #7 = Methodref #6.#23 // java/lang/StringBuilder."<init>":()V #8 = Methodref #6.#29 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #9 = String #30 // d #10 = Methodref #6.#31 // java/lang/StringBuilder.toString:()Ljava/lang/String; #11 = Fieldref #12.#32 // C.s1:Ljava/lang/String; #12 = Class #33 // C #13 = Class #34 // java/lang/Object #14 = Utf8 s #15 = Utf8 Ljava/lang/String; #16 = Utf8 s1 #17 = Utf8 <init> #18 = Utf8 ()V #19 = Utf8 Code #20 = Utf8 LineNumberTable #21 = Utf8 SourceFile #22 = Utf8 C.java #23 = NameAndType #17:#18 // "<init>":()V #24 = Utf8 java/lang/String #25 = Utf8 abc #26 = NameAndType #17:#35 // "<init>":(Ljava/lang/String;)V #27 = NameAndType #14:#15 // s:Ljava/lang/String; #28 = Utf8 java/lang/StringBuilder #29 = NameAndType #36:#37 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #30 = Utf8 d #31 = NameAndType #38:#39 // toString:()Ljava/lang/String; #32 = NameAndType #16:#15 // s1:Ljava/lang/String; #33 = Utf8 C #34 = Utf8 java/lang/Object #35 = Utf8 (Ljava/lang/String;)V #36 = Utf8 append #37 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #38 = Utf8 toString #39 = Utf8 ()Ljava/lang/String;{ java.lang.String s; descriptor: Ljava/lang/String; flags: java.lang.String s1; descriptor: Ljava/lang/String; flags: public C(); descriptor: ()V flags: ACC_PUBLIC Code: stack=4, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: new #2 // class java/lang/String 8: dup 9: ldc #3 // String abc 11: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V 14: putfield #5 // Field s:Ljava/lang/String; 17: aload_0 18: new #6 // class java/lang/StringBuilder 21: dup 22: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V 25: aload_0 26: getfield #5 // Field s:Ljava/lang/String; 29: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 32: ldc #9 // String d 34: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 37: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 40: putfield #11 // Field s1:Ljava/lang/String; 43: return LineNumberTable: line 1: 0 line 2: 4 line 3: 17}SourceFile: "C.java"
0 0
- I学霸官方免费教程十九:Java常用类之String类
- I学霸官方免费教程十八:Java常用类之Object类
- I学霸官方免费教程二十九:Java查找算法之二分法查找
- I学霸官方免费教程二十三:Java常用类之日期类 Date类 SimpleDateFormat类 Calendar类
- I学霸官方免费教程二十:Java常用类之StringBuffer类和StringBuilder类
- I学霸官方免费教程二十四:Java常用类之随机数 Math类和Random类
- I学霸官方免费教程二十一:Java常用类之包装类 自动装箱 自动拆箱
- I学霸官方免费教程二十二:Java常用类之接收控制台输入 Scanner类
- I学霸官方免费教程十六:Java面向对象之抽象类
- I学霸官方免费教程二十七:Java基础教程之Arrays类
- I学霸官方免费教程三十五:Java集合框架之Collection接口和Collections类
- I学霸官方免费教程四十四 :Java流之字文件File类
- I学霸官方免费教程三:Java基础之注释 关键字 标识符
- I学霸官方免费教程四:Java基础之数据类型 常量 变量 数据类型转换
- I学霸官方免费教程五:Java基础之运算符
- I学霸官方免费教程六:Java基础之流程控制
- I学霸官方免费教程八:Java基础之方法(函数)
- I学霸官方免费教程十:Java基础之关键字static和this
- [IOS开发]搜索用谓词NSPredicate
- SqlBulkCopy 高效、大数据量复制数据
- flask tutorial debug '_AppCtxGlobals' object has no attribute 'db'
- Lufylenged引擎学习——LTextField
- 28-反射机制-05-反射机制(获取Class中的字段)
- I学霸官方免费教程十九:Java常用类之String类
- 2015年8月11日--日常工作总结
- 关于xloader和uboot的几个初级问题
- DIV属性
- mysql备份
- LeetCode -- 顺时针旋转图片90度
- 9.9递归和动态规划(五)——确定某字符串的所有排列组合
- hdu 1247 Hat’s Words
- HDU 5374 Tetris(模拟俄罗斯方块)