1.String的数据类型
String 不属于基础类型,基础类型有 8 种:byte、boolean、char、short、int、float、long、double,而 String 属于对象
即引用数据类型
2.String类为啥不能被继承
String类是一个被final修饰的类(源码:public final class String)
3.String的底层实现
其实String的底层就是一个被final修饰的字符数组
private final char value[];实例化一个字符串,源码中还有很多构造器public String(String original) {this.value = original.value;this.hash = original.hash;}
4.String的常用方法
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
5.==与equals方法的区别以及equals方法到底是怎么一回事
- ==对于数据类型的不同作用效果是不同的
基本数据类型:比较的是值是否相同
引用数据类型:比较的是引用是否相同(实际上比较的是地址值)
String s1=new String("person");String s2=new String("person");Person p1=new Person();Person p2=new Person();System.out.println(p1==p2);//falseSystem.out.println(a==b);//trueSystem.out.println(s1==s2);//false
- equals:其实就是相当于==中引用数据类型的比较
源码
public boolean equals(Object obj) {return (this == obj);}
列:
Person p1=new Person();Person p2=new Person();System.out.println(p1.equals(p2));//false
为啥下面这个不是false呢?
String s1=new String("person");String s2=new String("person");System.out.println(s1.equals(s2));//true
基于以上这个问题看String源码就可以知道在String类中重写父类Object的equals方法
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}
6.两个对象hashcode()相同,则equals()也一定为true吗
public class Test01 {public static void main(String[] args) {String s1="通话";String s2="重地";System.out.println("s1的hashcode:"+ s1.hashCode());System.out.println("s1的hashcode:"+ s2.hashCode());System.out.println(s1.equals(s2));}}结果:s1的hashcode:1179395s1的hashcode:1179395false
但是两个对象的equals()为true,那么hashcode一定相同。
7.Java中操作字符串的有哪些类
- String,StringBuffer,StringBuilder
- String,StringBuffer,StringBuilder三者的区别在于String声明的是不可变的对象,而StringBuffer和StringBuilder是可以在原有的字符串的基础上操作。
- StringBuffer是线程安全的,但是它的效率是低于StringBuilder
8.String str=”i”与 String str=new String(“i”)一样吗?
不一样, String str=”i”是分配在常量池中,而String str=new String(“i”)是分配在堆内存中
9.String创建对象问题
- String str=”abc”;
大家肯定都知道都会创建一个对象,但是有没有可能没有创建对象呢?还真有可能,如果常量池中已经存在了”abc”,那么不会创建对象,直接将引用赋值给str.
- String str=new String(“abc”)又是创建了几个对象呢?1个还是2个?
同样的如果常量池没有abc那么创建2个对象,首先会在常量池中创建一个”abc”,然后执行new操作在堆内存中创建一个 String对象存储”abc”,对象的引用赋值给str。如果有,则创建一个String对象。
- String str=”abc”+”def”创建几个呢?
涉及到+号问题,当一个字符串由多个字符串拼接成一个字符串时,那它自己也是一个字符串,字符串常量的“+”号连接java虚拟机会在程序编译期将它优化为连接后的字符串,所以在编译时就已经是一个字符串了,因此只会创建一个字符串。没有创建临时的abc和def,这样减轻了垃圾回收器的压力。
- String str=”abc”+new String(“def”)创建了几个对象呢?
有可能都会说4个,abc,def,String对象和abcdef对象。但是不是全对,如果是创建了几个字符那对象,那就是对的,4个字符串对象。
看源码


由执行流程可以看出,java虚拟机在编译时创建了一个StringBuilder来进行字符串的拼接,所以有5个对象。
但是呢有些可能会认为有6个,最后的“abcdef”不在常量池中存一份吗?
看代码:
public static void main(String[] args) {String s="abc"+new String("def");String s1="abcdef";System.out.println(s==s1);//false}
10.如何将字符串反转
使用StringBuffer和StringBuilder的reverse()
// StringBuffer reverseStringBuffer stringBuffer = new StringBuffer();stringBuffer.append("abcdefg");System.out.println(stringBuffer.reverse()); // gfedcba// StringBuilder reverseStringBuilder stringBuilder = new StringBuilder();stringBuilder.append("abcdefg");System.out.println(stringBuilder.reverse()); // gfedcba
自己写一个字符串的反转方法。相信大家都会写。
