- 一、String类基本说明
- 二、关于String的两种创建方式的比较
- 三、String的常用方法
- 四、关于String的不可变性
一、String类基本说明
1.应该可以说是Java中最常用的类之一了,用于保存字符序列
2.使用Unicode字符编码,一个字符占用两个字节
3.常用构造器:
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int endIndex);
4.String 类实现了接口 Serializable和Comparable
表明String 可以串行化(可以在网络传输),可以比较大小
5.String类是final修饰的,表明它不能被继承
6.String内部封装了一个字符数组,这个字符数组是final修饰的,表明它一旦被赋值,则不可变。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
二、关于String的两种创建方式的比较
String a = "hello world";
String b = new String("hello world");
String a = “hello world”;//直接在常量池创建对象,把这个地址值赋给a
String b = new String(“hello world”);//先在堆中创建String对象,把这个对象的地址值赋给b,但是这个对象的value属性指向常量池中"hello world"的地址,如下图所示
其它说明:
- 常量池中的同一字符串只会有一份
- 对于常量相加,编译器会自动优化
String a = "ab"+"cd";
String a = "abcd"; // 编译器会优化
- 对于变量相加,底层使用的是StringBuilder进行拼接
String a = "hello";
String b = "world";
String c = a + b;
由此引出一些面试题
String s1 = "hello";
String s2 = "_world";
String s3 = "hello_world";
String s4 = "hello"+"_world";
String s5 = s1 + s2;
String s6 = new String("hello_world");
String s7 = new String("hello_world");
System.out.println(s3 == s4); // true s4编译器优化String s4 = "hello_world";和s3一样指向常量池
System.out.println(s3 == s5); // false 变量相加,会创建对象
System.out.println(s3 == s6); // false s6是new出来的,只要是new出来的,就不相等
System.out.println(s6 == s7); // false s6和s7都是new出来的,每new出一个,都会分配一个新地址
三、String的常用方法
String a = "hello world";
String b = new String("Hello world");
System.out.println(a.equals(b)); // false
System.out.println(a.equalsIgnoreCase(b)); //true
System.out.println(a.length()); // 5
System.out.println(a.indexOf("lo")); // 3
System.out.println(a.indexOf("a")); // 找不到返回-1
System.out.println(a.lastIndexOf("o")); // 7
System.out.println(a.substring(6)); // world
System.out.println(a.substring(6, 6 + 2)); // wo
String str = " 你好 人类 ";
System.out.println(str.trim());// 你好 人类 (只能去掉前后空格中间的空格保留)
System.out.println(a.charAt(6));// w
// System.out.println(a.charAt(11)); // StringIndexOutOfBoundsException
System.out.println(a.toUpperCase());
System.out.println(b.toLowerCase());
System.out.println(a.concat(" lalala").concat(" eee"));
System.out.println(a.replace("l", "5"));
String[] arrStr = a.split(" ");
String s1 = "abc";
String s2 = "abd";
System.out.println(s1.compareTo(s2)); // s1比s2小,返回负数
char[] chars = a.toCharArray();
String pattern = "你好,我叫%s,今年%d岁啦,工资每月%.2f";
String aaa = String.format(pattern, "小明", 20, 123.25833);
System.out.println(aaa);
四、关于String的不可变性
String str = "hello";
str = "world";
System.out.println(str); // world 这不是可变的吗?
这里的不可变,指的是String对象中的那个字符数组一旦被赋值,则不能改变。
这里能重新赋值,并不是改变了这个字符数组,而是断了之前的引用,重新在常量池分配字符串,对str这个变量进行了重新赋值。
可以debug看:
第一行代码走完:观察str的地址值
第二行代码走完:观察str的地址值,是直接指向了另一个地址
大概就这样吧
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)