# String

**Java 中的 String 类型有两个主要特性:**

1. String 不属于基本数据类型,而属于引用数据类型, 其本质是一个 对象。
2. &#x20;String 一旦实例化,无法对其内容进行更改,这点与其他语言不同。

另外 如需更改String的内容, 建议使用StringBuilder类型,下节将会详述。

String类型实例化非常简单:

```java
// 定义一个字符串"Java 编程 基础"
String str = new String("Java 编程 基础");
```

如需打印 直接使用System.out.println(String 对象)即可

```java
System.out.println(str);
```

**String 类型有许多常用方法:**

```java
// length 打印输出字符串的长度
System.out.println("字符串的长度是 : " + str.length());

// substring 去除字串"编程 基础"并输出
System.out.println(str.substring(5));
System.out.println(str.substring(5, 10));

// substring 取出字符 "程" 并输出
System.out.println(str.charAt(6));

// index 查找'a'字符串中第一次出现的位置
System.out.println("字符'a'在字符串中第一次出现的位置 : " + str.indexOf('a'));

// lastIndexOf 查找'a'字符串中最后一次出现的位置
System.out.println("字符'a'在字符串中第一次出现的位置 : " + str.lastIndexOf('a'));

// 从位置3开始，查找'a'字符串中第一次出现的位置
System.out.println("从位置8开始，字符'a'在字符串中第一次出现的位置 : " + str.indexOf('a', 3));
```

**此外, String对象还能和 byte\[] 数组之间进行相互转换, 数组在Java当中也是一个引用数据类型**

```java
// 将字符串转换为byte数组,并打印输出
byte[] arrs=null;
try {
		arrs = str.getBytes("GBK");// 也可以不指定编码格式,win默认GBK，mac默认UTF-8
		for (int i = 0; i < arrs.length; i++) {
			System.out.print(arrs[i]+" ");
		}
} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
} 

//将byte数组转换为字符串
String str1=new String(arrs);//也可以不指定编码格式,win默认GBK
System.out.println(str1);
```

**String 类对其父类 的equals 方法进行了重写, 比较的是字符串的值**

**String 类 == 符号比较的是两个对象的地址**

```java
String str1="java se";//str1是栈空间d额一个引用，指向常量池中的"java se"
String str2="java se";//str2是栈空间d额一个引用，也指向常量池中的"java se"
String str3=new String("java se");//str3是栈空间d额一个引用, 指向堆空间的new出来的对象
		
//String 类对其父类的 equals方法进行了重写，比较的是字符串的值
System.out.println("str1 和 str2 内容 相同吗? : "+(str1.equals(str2)));//true
System.out.println("str1 和 str3 内容 相同吗? : "+(str1.equals(str3)));//true


System.out.println("str1 和 str2 地址 相同吗? : "+(str1==str2));//true
System.out.println("str1 和 str3 地址 相同吗? : "+(str1==str3));//false
```

**String 类型的不可变性**

String 对象一旦创建,也就是new出来,不可更改

若给字符串重新赋值，则相当与new了一个新对象, 而不是对原对象的值进行修改

```java
String s1="java";//s1指向常量池里面java"
s1="hello,"+s1;//s1指向常量池里面的"hello,java"
System.out.println("s1="+s1);
		
//String 对象一旦被 new 出来，即不可变
//若给字符串重新赋值，则相当与new了一个新对象

//用对象==测试
System.out.println("s1 地址"+s1==(s1="python"));//输出false

//用对象hashcode测试, 两次输出不同
System.out.println(s1.hashCode());
s1="C++";
System.out.println(s1.hashCode());
```
