😶🌫️😶🌫️😶🌫️
String类
在C语言中,字符串不属于一个基本数据类型,C语言中的字符串只能使用字符数组或者字符类型的指针形式来存储,显然这只是一个组合型的数据组,由一个个字符组成。其中可以引用其标准库完成大多数字符串操作,但是这种与数据对象与操作分离的方式不符合java面向对象的特点。因此java专门设置了String类,java中字符串以对象的形式出现。
1.声明
在java中,字符串必须被包含在一对英文半角双引号:""内。例如
"123456789" 、 "ABCEDF" 、 "hello!你好呀!" 、 ""
以上都是字符串常量,其中""为空字符串。
声明:使用以下语法
String str;
其中str为变量名,其命名只要遵从基本命名规则即可。String 为字符串类型,声明该变量为字符串类型。如果str为局部变量,那么他必须在声明的时候初始化。
2、创建字符串
①创建字符串对象
java将字符串作为对象处理,因此可以像创建其他类对象一样来创建String对象:
String str = new String ( char a[ ] ) // char[] a 在语法上与 char a[] 等价
代码案例如下:
public class Main { public static void main(String[] args) { char a[] = {'a','b','c'}; char[] b = {'a','b','c'}; String strA = new String(a); String strB = new String(b); String strC = new String("good"); String strD = "hello"; String strE = new String(new char[]{'你', '好'}); System.out.println("strA的值为"+strA); System.out.println("strB的值为"+strB); System.out.println("strC的值为"+strC); System.out.println("strD的值为"+strD); System.out.println("strE的值为"+strE); } }
strA和strC的创建方式是等价的
输出结果为:
其中:
String strE = new String(new char[]{'你', '好'});
如果将其改为:去掉new
String strE = new String( char[]{'你', '好'});
就会报错,因为他是一个没有声明的变量,这里的new就相当于给他申明为一个字符数组,否则无法识别。
同时,java中相连的字符串不能分开在两行中写,这种语法是错误的,如下:
String str = new String ("hello
world");
会因为语法错误而不能通过编译
②字符串的存储形式
char a[]为字符串数组,当其传入的时候会自动调用构造方法,给对象的value传参,value的信息如下:
value是用来存放字符的
调用构造方法如下:
例如我们传入数组a
char a[] = {'a','b','c'};
调试,显示如下
所以本质上,字符串是以字符数组的形式存储的。
③字符串对象在内存中的布局
String strA = "abc";
String strB = "abc";
String strC = new String ("abc");
System.out.print ( strA == strB);
System.out.print ( strA == strC);
main函数里面新创建两个 strA 和 strB 对象,然后用 == 对其进行比较,因为他们都是引用的同一个字符串 "abc",所以结果为 true:
运算符" == " 比较的是两个字符串对象的引用地址,而不是字符串对象里面的内容,想要比较内容可以使用equals方法,这篇文章中有讲到,后面不在列出equals方法的使用。
而strA和strC,strA是指向"abc",而strC在堆区重新new了一个"abc"对象,他和之前已经存在的abc字符串是两个不同的对象。
在strB去创建的时候,"abc"这个字符串被放入了堆区的内存池中,strA指向这个在strB创建之前的字符串,当strB去创建一个字符串对象的时候,程序会首先去内存池查看是否已经存在相同内容的字符串,如果存在,就将其指向已经存在的字符串,否则就会生成一个新的字符串对象》》:
3、连接字符串
①连接字符串
对于一个字符串对象,我们可以使用 " + " 将其与 其他字符串对象 进行连接
代码如下:
public class Main { public static void main(String[] args) { String tem = "hello world"; String str1 = " ! hello java"; String exm = tem + str1; System.out.println(exm); tem += str1; System.out.println(tem); } }
其中直接将 一个字符串对象 tem 和另外一个字符串对象str1 相加,然后赋值给 一个exm字符串对象,然后打印。 对tem进行 += str1 操作,然后打印:
运行结果如下:
我们在创建字符串这个内容里面提到过,字符串不能在两行写,但是有的时候字符串内容过长,为了便于观看又不得不分两行写。所以这个时候就可以使用 "+ "将两个其分为两个字符串然后相加:
String str = new String ("hello" +
" world " );
②连接其他类型
java中通过 " + "也可以让String字符串对象 和其他数据类型的数据进行连接,通过 + 会直接将其合并为字符串:
public class Main { public static void main(String[] args) { String tem = "hello world" + 0; System.out.println(tem); tem += true; System.out.println(tem); tem += 1.5F; tem += 2.66; System.out.println(tem); tem += 'a'; System.out.println(tem); tem = "xxxxxxx" + tem; System.out.println(tem); } }
运行结果如图:
可以看到,一个字符串类型可以使用 " + " 或者" += " 将多个基本数据类型相连,组合成为一个新的字符串,无论是在其左端还是右端,都可以,其中浮点数后面的F(f),长整型后面的L(l)在和字符串进行加法的时候不会被加入到字符串当中。
对于相加的其他数据类型,也存在着括号优先级的问题。例如
public class Main { public static void main(String[] args) { System.out.println("hello world " + 123 + (1 + 2) +"i like java"); } }
他会优先计算 圆括号中的 1 + 2 的内容,然后和字符串进行加法,结果如下:
但是圆括号内的内容计必须是可两个可以进行 + 运算的数据类型,例如:
public class Main { public static void main(String[] args) { System.out.println("hello world" + 1.265 + (0.123 + false) +" i love java! " ); } }
就会因为类型不匹配而报错:
字符串和别的基本数据类型的加法,极大地方便了我们去表示和描述一串有几个不同数据类型组合而成的数据。
③ 面试题
(多选题)关于下面的一段代码,哪些说法是正确的?
public static void main(String[] args) { String a = new String("myString"); String b = "myString"; String c = "my" + "String"; String d = c; System.out.print(a == b); System.out.print(a == c); System.out.print(b == c); System.out.print(b == d); }
A .System.out.print(a == b)打印出来的是false
B .System.out.print(a == c)打印出来的是true
C .System.out.print(b == c)打印出来的是false
D .System.out.print(b == d)打印出来的是true
解析:
a为String构造方法,在堆区创建的对象
b为常量字符串,被放入了对区中的常量池
c为字符串的拼接,如果"+"两边为字符串变量或者一个为字符串常量,一个为变量,则会在底层将变量转化为StringBuilder然后通过append的方式追加,再将其通过toString方法转化为String字符串,最后通过构造方法new出这个String字符串对象。如果都为常量,由于java优化机制,拼接的结果会直接转向内存池,在内存池中查找是否具有相同内容的字符串,如果有则直接指向这个已经存在的具有相同内容的常量字符串,如c选项,c和b都是引用的同一个字符串常量。
d直接引用c对象的地址。此时b,c和d同时指向同一个字符串
因此答案为AD
javaString类超详解-2