您的位置:首页 > 编程语言 > Java开发

12-6java面向对象之String类

2014-12-06 09:45 706 查看
今天主要为大家讲解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,对于使用方法的介绍,加深了对内存操作的学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: