[零基础学JAVA]Java SE面向对象部分-08.面向对象基础(03)

  1. 云栖社区>
  2. 博客>
  3. 正文

[零基础学JAVA]Java SE面向对象部分-08.面向对象基础(03)

技术小美 2017-11-12 10:40:00 浏览780
展开阅读全文
上季内容回顾:
1、封装性 
· 对外不不可见,属性前加入private关键字 
· 通过setter和getter方法设置和取得封装属性
 
2、构造方法 
· 与类名称相同,无返回值类型 
· 在对象实例化(new)的时候被自动调用 
· 构造方法可以重载 
· 每个类中至少有一个构造方法
 
3、匿名对象:只使用一次的对象。
本季目标 
1、 String类及常用方法  
        本季详细讲解了JAVA中最常用的类 —— String的具体操作,包括字符串的比较,String类的特性,以及String类中一系列方法(包括赋值方法)的使用。
String类
image
因为String可以直接赋值 
String肯定是一个类,如果按之前的理解,一个类要想使用必须使用new开辟空间或者把其他对象的引用传递过来。
image
String能否采用new的方式赋值呢?我们现在不知道哈~那我们就查下JDK文档哈~
image
在JavaTM 2 Platform Standard Edition 5.0 API规范中我们在索引查找String哈
image
image
image
我们看到其有点像整型变量哈,我们继续往下看对象的比较哈~
对象的比较
image
image
我们发现str1和str2输出都是abc,但是比较后的结果却是false哈~
image
别着急哈,我们再定义一个str3,将str2的内容赋值给str3,这样str2和str3同时指向同一个堆内存空间,然后我们再比较str2和str3
image
我们看下效果哈~
image
我们发现str2和str3相比是true,为什么哈?实际上,在这个过程中,我们一起使用的是“==”比较哈,在int或其他基本数据类型之中,可以使用“==”进行是否相等的验证,那么在String中,因为String本身虽然可以直接像基本数据类型那样直接赋值,但是其依然要依靠内存的指向。
image 
· “==”如果直接应用在字符串上进行比较,则表示比较的是内存地址的值。 
· 如果要比较字符串里面的内容,则肯定要使用一个方法:此方法为String类的内部提供的一个方法:public boolean equals(String str)  ==> 比较两个字符串是否相等。 
· equals比较两个字符串的内容是否相等的。
如果equals的方法我们不知道哈,那我们还是查找JDK文档哈~
image
从上面ooDemo01我们知道String是一个类,那str1、str2及str3就肯定是一个对象哈,我们可以这样写类似代码哈str1.equals()来调用equals方法。
image
我们看下效果,我们发现str1、str2及str3相互比较的话,现在都相等,输出true了哈~
image
从而我们得到一个结论哈~: 
“==”表示比较的是内存地址的值 
equals表示比较两个字符串的内容是否相等
在面试中经常会问到一个样这样的问题:说明“==”与equals的区别?区别的答案就是上面的结论哈~
String类中的内容一旦声明则不可改变,这句话怎么理解呢? 
String有匿名对象—— 字符串 
现在我们假设有“abc”这样一个字符串,“abc”就是String的匿名对象。
匿名对象是不是对象呢?我们知道当然是对象哈,那为什么“abc”就是匿名对象呢?我们看ooDemo03来理解哈~
image
如果"abc"是一个匿名对象哈,那我们肯定可以使用"abc".equals(str1)来比较"abc"和str1的内容是否相同哈,我们看下效果,程序执行输出为true,证明我们的推断哈~“abc”肯定是一个匿名对象。
image
这样我们就很好理解String str = "abc"是把一个字符串的匿名对象赋值给String的一个对象str。
String类中的内容一旦声明则不可改变,现在我们就来理解这句话哈~,我们来观察以下ooDemo04程序,分析内存,得出String是不可改变的哈~
image
image
哈~有人说这可以改变哈~实际上不是这么回事哈,它根本没有改变,我们来分析下内存操作哈~~
String str1="abc";证明栈内存中有个str1,在堆内存中的内容是abc。
image
str1 +="def"; 首先是先有“def”在堆内存中开辟空间哈~
image
然后再进行str1 + "def"运算所得的字符串“abcdef”又在堆内存开辟空间哈~
image
原来str1指向的是“abc”所占的堆内存空间,现在str1 + "def"运算所得的字符串“abcdef”又赋值给str1,所以str1先断开指向“abc”的连接,最后str1就指向“abcdef”新的空间与其建立连接。
image
总结:虽然以上的显示效果String的内容改变了,但是实际上而言,String改变的只是其内存地址的指向,而其本身的内容没有被改变。所以说我们以后不要这样写代码哈,因为这样影响程序的性能哈~
例如以下一段代码:
image
我们发现,程序执行效果还是输出了哈,但是其每一步的运算都要进行内存的转换才能赋值给str1哈,循环运算100次哈,那么内存地址引用也要断开重新连接100次哈,如果次数一多肯定会影响程序性能。
image
所以以上代码的性能是很差的,因此在开发中坚决不建议这样使用,如果非要有以上的要求,则可以使用另外一个类——StringBuffer,String的缓冲操作,这个类是可以改变的哈~~~这个我们以后再讲哈~
现在我们再来理解String是JAVA中共享模式的一种应用这句话哈~这是很多初学者最难理解的部分,我们来看下面一个例子ooDemo06
image
我们发现str1和str2比较的话是相等的哈~
image 
之前说,只要是字符串就是一个String 的匿名对象吗?但是在String 类中如果一个字符串已经明确有了一个对象的指向,则以后其他的String对象如果声明的内容是一样的,则自动指向同一个空间。
我们还是来分析下内存的实际操作哈~
首先是String str1="abc";这个我们现在都理解了哈~
image
紧接着是String str2="abc";代码哈,我们可能会想当然的认为在内存操作是这样的哈~
image
那我们说原来的“abc”有没被引用到,我们知道原来的“abc”已经被str1引用,那么就不可能再生成另外一个“abc”,只会将原来的“abc”地址指向str2,那现在str1和str2都指向同一个内存空间地址,比如“abc”内存空间地址为0x1000哈,我们进行System.out.println(str1==str2);代码中进行“==”比较时得到的运算结果就是true了哈~所以说如果内存中已经有相同内容的地址话,我们就不要再开辟新的空间了,如果没有的话,那我们就要重新声明开辟新的空间。
image
还有一个问题哈:String类直接赋值和使用new开辟空间有什么区别?该使用那个?
这个问题我们用所说到的知识来分析哈~
直接赋值
image
image
如果使用new来赋值
image
在String str1 = new String("abc") ;代码中我们知道“abc”是匿名对象,那么在堆内存中就会有块空间是“abc”,紧接着new String("abc") 使用new在堆内存中又开辟了一个空间“abc”,最后String str1 = new String("abc") ;代码将最后生成的“abc”内存地址指向str1,最早的一个“abc”就没使用上。
image 
String str1 = new String("abc") ; 
会在堆内存中产生两个对象,其中有一个是无用的。 
综合以上来说,肯定是直接使用赋值的方式比较合适一些,因为只产生一个对象,而如果使用new 关键字开辟,则会产生两个对象。
在对象的比较中,我们还有个问题哈,如何比较两个对象的内容是否相等。
我们定一个这样的要求哈: 
定义一个Person对象,里面包含name 和age,产生两个Person对象,如果姓名和年龄相等,则认为两个对象表示的是同一个人。
image
我们程序执行下哈~ok,程序显示是同一个人哈~
image
这样就比较两个对象的内容是否相等哈。
String作为系统提供好的一个类,在实际开发中有很大的作用,而且String操作方法也很多哈~
1、 求出字符串的长度:public int length() ;
我们还是来查JDK文档哈~
image   
image
ok,是34个哈~这样我们就求出字符串的长度了哈~
image
小的记忆错误: 
· 数组的长度:数组名称.length     这个没()哈~~ 
· 字符串的长度:调用的是里面的方法:字符串对象.length()    
这个有()哈~

2、将一个字符串变为字符数组:public char[] toCharArray()
image
image
image
确实把字符串一个个拆开转换成数组了哈~
image
3、将一个字符串按指定的字符分割:public String[] split() ;
这个方法很重要哈~以后使用会很多滴~
 image
image
image
我们看下效果,确实按“:”进行拆分了哈~
image
4、截取字符串 
· public String subString(int beg) 
· public String subString(int beg,int end)
image
image
我们现在将定义的字符串[url]http://redking.blog.51cto.com[/url],让其输出redking.blog.51cto.com字符哈~
image
ok哈~
image
如果只让其输出redking呢?
image
image
5、替换方法,把一个字符串中的某个指定的字符替换成其他内容 
public String replaceAll(String 原字符串,String 要替换的新字符串)
image
image
image
已经替换了哈~
image
6、去掉左右空格,输入数据的时候常使用哈~ 
public String trim() ;
image
image
image
去掉左右空格了~
image
7、将所有的字符串变为大写或小写
image
字符串Michael已经都变为大写和小写了哈~
image
8、判断一个字符串是否以指定的字符串开头或结尾 
· public boolean startsWith(String str):判断是否以str开头 
· public boolean endsWith(String str):判断是否以str结尾
image
image
9、查找在一个字符串中是否有指定的字符串存在。 
public int indexOf(String str):查找在一个字符串中是否包含了str,如果包含了,则返回位置,如果没有查到,则返回-1;
image
image
我们看下实例哈~
我们查下字符串中有没大写的"X"哈~
image
字符串$_$Michael@_@中没有大写的X哈,所以程序返回-1哈~
image
那我们来查找下字符串中有没大写的"M"哈~
image
我们知道字符串中是有大写M的哈,所有下标都是从0开始,所以返回大写“M”其位置3哈~
image 
我们可以利用返回值-1的关键来判断是否查找到要查询的字符串~
image
验证下,看看效果哈~
image
我们讲了下String中常用的方法哈,要深入研究就翻翻JDK文档哈~
总结
String类: 
· 不可改变,如果要改变,改变的是内存地址的指向 
· 两种赋值方式的区别,使用直接赋值 
· String的内容比较使用equals,==比较的是内存地址的值 
· String中的各种常用方法。






本文转自redking51CTO博客,原文链接:http://blog.51cto.com/redking/122142,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术小美
+ 关注