public boolean equals(Object obj) {
return (this == obj);
}
面试题:
一、下面的代码将创建几个字符串对象
String s1 = new String(“Hello”);
String s2 = new String(“Hello”);
答案: 3个
new这个关键词, 毫无以为会在堆中分配内存, 创建一个String类对象, 因此s1在栈中的引用指向堆中的这个String对象, 因为"Hello"是一个常量, 所以会去常量池中找有没有这个常量存在, 没有的话会在常量池中分配一个空间, 存储这个常量, 并将这个常量对象的空间地址给到堆中的String对象; 如果常量池中已经有了这个常量,就直接用那个常量池中的常量对象的引用呗,就只需要创建一个堆中的String对象。
注意: JDK1.7之后, 方法区的常量池被移动到堆中
二、字面量+字面量
创建了一个对象
String s = "abc" + "def"
当+号两端都是编译期确定的字符串常量时, 编译器会进行相应的优化, 直接将两个字符串常量拼接好, 放到常量池中, 所以只会创建一个"abcdef"对象
二、字面量+对象
创建了三个对象
String s1="abc";
String s2 ="abc"+s1+"def";
s1="abc"一个
s2中:"abc"已经存在,不再创建,"def"一个,"abcdef"一个
三、new String(“xx”) + new String(“xx”)
创建4个String对象
String s = new String("abc") + new String("abc");
第一个new String(“abc”)创建了两个
第二个new String(“abc”)创建了一个(常量池中有"abc"不再创建)
new String(“abc”) + new String(“abc”)一个
ps: 两个字符串相加会在堆上创建1个String对象”abcabc”(因为没有显式使用双引号指定,也没有调用intern,所以常量池里边目前没有“abcabc”对象)
String s = new String("abc") + new String("def");
这种情况下, 则会创建5个对象
String | StringBuffer | StringBuilder | |
---|---|---|---|
可变性 | 不可变 | 可变 | 可变 |
线程安全性 | 线程安全 | 线程安全 | 线程不安全 |
一、可变性
String是不可变的对象(final修饰), 所以每次修改String类型变量, 实质上都等同于生成一个新的String对象, 然后将指针指向新的String对象
String对象的字符内容是存储在一个字符数组value[]中, 而这个value[]是被final修饰
这样不仅效率低下, 而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String. 因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢
StringBuffer、StringBuilder的父类AbstractStringBuilder的value数组不是final类型
二、线程安全性
String的线程是安全的, 因为value数组是final
StringBuffer是线程安全的, 因为他的方法使用了synchronized(单线程时没必要使用, 因为加锁了, 速度慢)
StringBuilder是线程不安全的(单线程时建议使用,因为没加锁,速度快)
在java中存在8种基本类型以及一种特殊的类型String, 这些类型为了使它们在运行过程中速度更快, 更节省内存, 都提供了一种常量池的概念(在方法区), 常量池相当于java系统提供的缓存
String类型的常量池比较特殊, 主要使用方式有两种
String不可变的含义: 将一个已有字符串"123"重新赋值为"456", 不是在原内存地址上修改数据, 而是重新指向一个新对象、新地址
也就是说, 不可变的含义是内部数据不可变, 而非引用不可变
String str= "123";
str = "456";
System.out.println(str);
与类的加载顺序有关, 加载静态方法时, 非静态的还未初始化
为什么要对unchecked异常和checked异常进行区分?
编译器将检查你是否为所有的checked异常提供了异常处理机制, 比如使用Class.forName()来查找给定的字符串的class对象的时候, 如果没有为这个方法提供异常处理, 编译将无法通过
finally语句与return语句详解
字节流、字符流、缓冲流
字节流和字符流的使用非常相似