字符串是一个对象
-
Java当中只有两种数据类型:基本类型、引用类型
-
基本数据类型只有八个关键字,所以字符串是一种引用类型
-
注意:java中只要是字符串,就是一个对象
public class Demo01String {
public static void main(String[] args) {
//动态初始化一个数组,这就是创建了一个对象。数组就是一个对象
int[] array1 = new int [5];
// 静态初始化一个数组,也是一个对象
int[] array = {1,2,3,4,5};
// 字符串直接写上双引号,就是一个String类型的对象,String就是类名称
//String为类名称 ,str为对象名,“Hello”为堆内存中的字符串对象
String str = "Hello";
System.out.print(str); //Hello
//直接使用的字符串常量,也照样是一个字符串对象!
System.out.println("World");
}
}
- 字符串的两个问题:
1.字符串对象有一个对应的类,对应String
- 为什么String这个类,不需要导包就能直接使用?
- 所有类都需要导包才能使用,除了两种情况:
- A. 要使用的目标类,和当前类位于同一个包下
- B.要使用的目标类,位于java.lang包下 (jdk/lib/src/java.base/java/lang)。但是不包含子包。
2.既然字符串是对象,那么为什么直接打印出来就是内容呢?怎么不是new出来的地址值呢?
- 打印println方法逻辑:
a.如果是字符串类型,直接显示内容。
b.如果不是字符串类型,那么就想办法转换成字符串,然后再显示。
一般的对象都是使用 “类型信息+@+地址值” 作为字符串内容
public class Demo02StringQuestion {
public static void main(String[] args) {
String str = "Hello";
System.out.println(str); //hello
Person per = new Person();
System.out.println(per); //abc.Person@136432db
}
}
字符串的构造方法
字符串创建常见的2+1种方式(两种构造方法,一种直接赋值)
-
常用的两个构造方法:
public String(char[] array):参数是一个字符数组,根据字符数组的内容来创建一个字符串
public String(char[] array,int offset,int count):根据字符数组的一部分内容来创建字符串。
参数offset代表一个偏移量,代表数组中的起始索引,从0开始。
参数count代表取用多少个字符。
注意不要超出范围直接赋值双引号也是一个字符串对象:
String str = “Hello”;
public class Demo03StringInit {
public static void main(String[] args) {
char[] array = { 'H', 'e', 'l', 'l', 'o' };
// 根据字符数组来创建字符串
// 类名称 对象名 = new 类名称(构造参数)
String str1 = new String(array);
System.out.println(str1); // Hello
//根据字符数组一部分来创建字符串
String str2 = new String(array,2,3);
System.out.println(str2); //llo
//如果制定的索引或者个数超出了合理范围,那么将发生索引越界:
//String str3 = new String(array,100,200);
//直接赋值
String str4 = "HelloWorld";
System.out.println(str4); //HelloWorld
}
}
字符串池
字符串是最为常用的对象,所以在程序当中往往会出现很多个重复的字符串。
为了节省内存,所以引入了“字符串池”的设计,可以重复利用字符串。
关于字符串池的几点描述:
1.字符串池是位于堆内存中的一小块儿空间,用来保存若干个字符串的地址值。
2.字符串池中绝对不会出现重复的字符串对应的地址,重复字符串拥有相同的地址值,达到节省内存的目的。
3.凡是直接双引号的赋值字符串默认都在池里,而new出来的字符串默认不在池里。
对于基本类型来说,==是进行数据内容的比较。
对于引用类型来书,==是进行地址值的相同比较。
如果是两个对象,那么地址值必然不同,如果地址值相同,必然是同一个对象。
public class Demo04Pool {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); //true
char[] array = {'H','e','l','l','o'};
String str3 = new String(array);
String str4 = new String(array);
System.out.println(str3 == str4); //false
System.out.println(str1 == str3); //false
}
}
字符串的内容不可变
字符串是常量;它们的值在创建之后不能更改。
字符串的内容不会发生改变,每当你觉得字符串内容变了,一定是创建了新的字符串,改变地址,指向新的空间。
public class Demo05Eternal {
public static void main(String[] args) {
// 字符串赋值变化,是字符串地址值在变,而不是字符串在变
String str = "Hello";
System.out.println(str); // Hello
str = "World";
System.out.println(str); // World
//两个字符串相加,会在堆内存中创建第三个字符串
String str2 = "Love";
str2 += "Java";
System.out.println(str2); // LoveJava
//str2得到新的地址LoveJava的地址
}
}