12-6java面向对象之String类

来源:互联网 发布:淘宝开发团队多少人 编辑:程序博客网 时间:2024/04/19 03:42

今天主要为大家讲解String类的使用。我们之前编写代码的过程中就发现,String的首字母大写,这个类的命名规则相同,所以断言String是一种系统类。

1.实例化方法

String的实例化方法有两种:
(1)直接赋值方法,这种方法之前普遍使用。  String str="hello";
(2)构造方法,由于String是类,肯定有自己的方法。
默认存在着public String (String str);必须使用new进行对象的实例化。
String str= new String(“hello”);
<img src="http://img.blog.csdn.net/20141206141255866?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmFvYmVpemhhbnNoZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />


2.字符串的比较

由于存在两种不同的实例化方法,他们之间有什么区别的?联想到数值之间的比较使用“==”,我们用“==”对其进行分析。
class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = new String("hello");System.out.println(str2==str1);}}


发现这种比较的结果是false说明str1和str2并不相等,这与我们的认识有不同,原因在哪呢?显然str1和str2的内容相同,这里既然给出了false,说明不是比较的内容,那么又是什么呢?
查询书籍发现,这种方法进行比较的是地址,用内存图进行说明。



显然在堆内存中开辟出两个不同的地址。那如果是要比较两个字符串的内容又该用哪种方式呢?因为String是类,理论上它应该有许多的方法,必然会有一种方法能够完成,查询发现:
public boolean equals(String other)
class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = new String("hello");System.out.println(str2.equals(str1));}}



使用一个程序将两中比较方式全部综合起来,并用内存图解释。
class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = new String("hello");String str3 = str2;//类的引用传递System.out.println("使用==进行地址的比较结果");System.out.println(str1==str2);System.out.println(str1==str3);System.out.println(str2==str3);System.out.println("使用equals方法进行内容的比较结果");System.out.println(str1.equals(str2));System.out.println(str1.equals(str3));System.out.println(str3.equals(str2));}}


可以看出结果的不同,内存图如下:



如果是用==进行地址的比较,那么str2和str3才能相等,如果是比较内容,则都相同。

3.匿名对象

直接赋值的方法,其实引入的是一个String类的匿名对象,他可以直接调用方法。例如:
class StringTest {public static void main(String[] args) {String str = new String("hello");System.out.println("使用equals方法进行内容的比较结果");System.out.println("hello".equals(str));}}

说明了匿名对象的使用,这里有个技巧,如果某个对象只声明,但是没有实例化,那么他并不能使用方法,如果要进行比较注意使用方法的对象一定要是实例化的。
class StringTest {public static void main(String[] args) {String str = null;//只声明了该对象System.out.println("使用equals方法进行内容的比较结果");System.out.println(str.equals("hello"));}}


提示指向异常,但是如果修改代码就没有问题。
class StringTest {public static void main(String[] args) {String str = null;//只声明了该对象System.out.println("使用equals方法进行内容的比较结果");System.out.println("hello".equals(str));}}

4.实例化的区别

有以上两种实例化的方式有什么不同呢?这里主要使用内存图进行表达解释。
使用直接赋值语句

这时候只在堆内存中开辟了一个空间存储。
使用构造方法

此时“hello”首先在堆内存中产生了一个空间,之后,在使用new进行实例化的过程中,hello被GC收集了。

注意:

class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = "hello";String str3 = "hello";System.out.println("使用==进行地址的比较结果");System.out.println(str1==str2);System.out.println(str1==str3);System.out.println(str2==str3);}}


比较发现,以上开辟的三个空间的地址是完全相同的,说明了直接赋值使用了共享设计模式。在程序中设计了一个对象池,如果实例化的内容相同,先判断这个池子是否有相同的,有的话继续使用;如果是新的,则创建。

但是如果采用的是构造方法呢?
class StringTest {public static void main(String[] args) {String str1 = new String("hello");String str2 = new String("hello");String str3 = new String("hello");System.out.println("使用==进行地址的比较结果");System.out.println(str1==str2);System.out.println(str1==str3);System.out.println(str2==str3);}}


这说明使用构造方法不会产生共享,只会不断的开辟新的空间内容。但是有一种方法能够手工入池
public String intern();
class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = new String("hello").intern();String str3 = new String("hello").intern();System.out.println("使用==进行地址的比较结果");System.out.println(str1==str2);System.out.println(str1==str3);System.out.println(str2==str3);}}



已经手工入池了。但是这种方式比较麻烦,开发多使用直接赋值的方式。

5.字符串声明就不能改变

但是可以改变字符串对象。
总结:本课程主要学习String,对于使用方法的介绍,加深了对内存操作的学习。
0 0
原创粉丝点击