Java基础知识整理-String类

先思考下以下问题:

1.String类能被继承吗?

String类被final修饰符所修饰,被final修饰符所修饰的类是不能被继承的。不过final修饰符除了锁定方法(类),防止继承,覆盖外,还有一个内联函数的功能
什么是内联函数?
定义在这里我就不搬运了,有兴趣可以深入了解,简单的说就是拿空间换时间,内联过的函数,直接在函数体内把调用的函数展开了,这样势必增加了代码的体积,不过却节省了调用函数压栈和弹栈的时间,针对热点代码可以考虑使用,属于编译器优化

2.String是基本数据类型吗?

创建String对象一般使用下面的形式,而不用new

String str="hello";

但是String却不是基本数据类型,而是引用数据类型
String也可以通过构造函数来创建对象:

String str=new String("hello");

不过上面两种方式有很大的区别:
第一种:该方法会先去字符串常量池中找是否有"hello"这个对象,如果有则直接返回,如果没有就创建一个,将引用指向该对象的同时,将此对象放入字符串常量池中,下一次再使用这中方式来创建一个"hello"String对象时,直接将字符串常量池中的"hello"对象返回,指向新的引用,并不会创建新的对象,代码如下:

String s1 = "hello";
String s2 = "hello";
boolean b1 = s1 == s2;
System.out.println(b1);

结果:

true

第二种:该方法不会去查看字符串常量池,直接创建一个新的对象,使用完之后也不会将新创建的对象返回到字符串常量池,代码如下

String s1 = "hello";
String s3 = new String("hello");
boolean b2 = s1 == s3;
System.out.println(b2);

结果:

false
3.如何比较两个字符串

String类重写了Object的equals方法,直接使用equals方法比较两个字符串即可,==是比较地址值,此处省略800字源码分析,String底层实现是一个有序的char数组

4.String,StringBuilder,StringBuffer的区别

(1).首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:
StringBuilder > StringBuffer > String

String最慢的原因:

String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:

String str="abc";
System.out.println(str);
str=str+"de";
System.out.println(str);

如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。

而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

另外,有时候我们会这样对字符串进行赋值

String str="abc"+"de";
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
System.out.println(str);
System.out.println(stringBuilder.toString());

这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和

String str="abcde";
是完全一样的,所以会很快,而如果写成下面这种形式
String str1="abc";
String str2="de";
String str=str1+str2;

那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。

(2). 再来说线程安全

在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

(3). 总结

String:适用于少量的字符串操作的情况

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

5.包装类.toString、String.valueOf(包装类)、包装类+"" 这三种方式都能实现由包装类到字符串的转换,有什么区别?

1、String.valueOf()方法底层调用了Integer.toString()方法,但是会在调用前做空判断
2、Integer.toString()方法就不说了,直接调用
3、i + ""底层使用了StringBuilder实现,先用append方法拼接,再用toString()方法获取字符串

三者对比下来,2最快、1次之、3最慢

你可能感兴趣的:(Java基础知识整理-String类)