12-6java面向对象之String类
2014-12-06 09:45
706 查看
今天主要为大家讲解String类的使用。我们之前编写代码的过程中就发现,String的首字母大写,这个类的命名规则相同,所以断言String是一种系统类。
(1)直接赋值方法,这种方法之前普遍使用。 String str="hello";
(2)构造方法,由于String是类,肯定有自己的方法。
默认存在着public String (String str);必须使用new进行对象的实例化。
String str= new String(“hello”);
发现这种比较的结果是false说明str1和str2并不相等,这与我们的认识有不同,原因在哪呢?显然str1和str2的内容相同,这里既然给出了false,说明不是比较的内容,那么又是什么呢?
查询书籍发现,这种方法进行比较的是地址,用内存图进行说明。
显然在堆内存中开辟出两个不同的地址。那如果是要比较两个字符串的内容又该用哪种方式呢?因为String是类,理论上它应该有许多的方法,必然会有一种方法能够完成,查询发现:
public boolean equals(String other)
使用一个程序将两中比较方式全部综合起来,并用内存图解释。
可以看出结果的不同,内存图如下:
如果是用==进行地址的比较,那么str2和str3才能相等,如果是比较内容,则都相同。
这说明了匿名对象的使用,这里有个技巧,如果某个对象只声明,但是没有实例化,那么他并不能使用方法,如果要进行比较注意使用方法的对象一定要是实例化的。
提示指向异常,但是如果修改代码就没有问题。
使用直接赋值语句
这时候只在堆内存中开辟了一个空间存储。
使用构造方法
此时“hello”首先在堆内存中产生了一个空间,之后,在使用new进行实例化的过程中,hello被GC收集了。
比较发现,以上开辟的三个空间的地址是完全相同的,说明了直接赋值使用了共享设计模式。在程序中设计了一个对象池,如果实例化的内容相同,先判断这个池子是否有相同的,有的话继续使用;如果是新的,则创建。
但是如果采用的是构造方法呢?
这说明使用构造方法不会产生共享,只会不断的开辟新的空间内容。但是有一种方法能够手工入池
public String intern();
已经手工入池了。但是这种方式比较麻烦,开发多使用直接赋值的方式。
总结:本课程主要学习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,对于使用方法的介绍,加深了对内存操作的学习。
相关文章推荐
- 12-6java面向对象之String类常用方法的总结
- Java面向对象基础--String类
- java学习日记_12:面向对象之如何使用类
- 【学习笔记12】java面向对象-多态
- Java面向对象-String类作业一字符串反转
- Java面向对象基础--String类中常用的方法
- 12-23java面向对象之多线程
- java学习之旅39--面向对象_12_继承_方法的重写
- Java面向对象-String类作业一字符串转数组
- 面向对象基础 (java4 Android 12,13,14,15集)
- java面向对象中的String类中12种常用的方法
- 12-21java面向对象之异常
- 12-9java面向对象之链表操作
- Java面向对象-String类(上)
- JAVA笔记四(12-15 面向对象基础)
- 12-5Java面向对象笔记(一)
- 12-15java面向对象之多态性操作
- 12-20java面向对象之Object类&包装类&匿名内部类
- Java面向对象-String类
- Java面向对象-String类(下)