第三天 面向对象.docx
《第三天 面向对象.docx》由会员分享,可在线阅读,更多相关《第三天 面向对象.docx(50页珍藏版)》请在冰豆网上搜索。
![第三天 面向对象.docx](https://file1.bdocx.com/fileroot1/2022-11/30/f301a7df-e279-46df-986e-7f15c5f0f447/f301a7df-e279-46df-986e-7f15c5f0f4471.gif)
第三天面向对象
第三天面向对象_02
3.1、String类(重点)
3.1.1 、String类两种对象实例化方式
对于String在之前已经学习过了基本使用,就是表示字符串,那么当时使用的形式采用了直接赋值:
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="Hello"; // 定义字符串
System.out.println(str);
}
}
对于String而言肯定是一个类,那么程序之中出现的str应该就是这个类的对象,那么就证明以上的赋值操作实际上就表示要为String类的对象进行实例化操作。
但String毕竟是一个类,那么类之中一定会存在构造方法,String类的构造:
publicString(Stringstr);
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr=newString("Hello"); // 定义字符串
System.out.println(str);
}
}
发现现在也可以通过构造方法为String类对象实例化。
3.1.2 、字符串比较
如果说现在有两个int型变量,如果要想知道是否相等,使用“==”进行验证。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
intx=10;
inty=10;
System.out.println(x==y);
}
}
但是,同样的操作,现在换成String完成。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr1="Hello";
Stringstr2=newString("Hello");
Stringstr3=str2; // 引用传递
System.out.println(str1==str2); //false
System.out.println(str1==str3); //false
System.out.println(str2==str3); //true
}
}
发现使用“==”好象最终的判断结果完全是不一样的,那么下面通过内存关系图完成。
现在使用了“==”的确是完成了相等的判断,但是最终判断的是两个对象(现在的对象是字符串)判断是否相等,属于数值判断 —— 判断的是两个对象的内存地址数值,并没有判断内容,而要想完成字符串内容的判断,则就必须使用到String类的操作方法:
publicbooleanequals(Stringstr)(将方法暂时变了)。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr1="Hello";
Stringstr2=newString("Hello");
Stringstr3=str2; // 引用传递
System.out.println(str1.equals(str2)); //true
System.out.println(str1.equals(str3)); //true
System.out.println(str2.equals(str3)); //true
}
}
现在比较的不再是内存地址的数值,而是两个字符串的内容。
面试题:
请解释字符串比较之中“==”和equals()的区别?
· ==:
比较的是两个字符串内存地址的数值是否相等,属于数值比较;
· equals():
比较的是两个字符串的内容,属于内容比较。
以后进行字符串相等判断的时候都使用equals()。
3.1.3 、字符串常量是String的匿名对象
如果在程序之中定义了字符串(使用“"”),那么这个就表示一个String对象,因为在各个语言之中没有关于字符串数据类型定义,而Java将其简单处理了,所以感觉上存在了字符串类型。
范例:
验证字符串是对象的概念
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="Hello";
// 通过字符串调用方法
System.out.println("Hello".equals(str));
}
}
匿名对象可以调用类之中的方法与属性,以上的字符串可以调用了equals()方法,那么一定是一个对象。
小技巧:
关于字符串与字符串常量的判断
例如:
在实际工作之中会有这样一操作,要求用户输入一个内容,之后判断此内容是否与指定的内容相同。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="Hello"; // 假设是输入的
if(str.equals("Hello")){
System.out.println("条件满足。
");
}
}
}
但,既然数据由用户自己输入,那么就有可能没有输入的内容。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr= null ; // 假设是输入的
if(str.equals("Hello")){
System.out.println("条件满足。
");
}
}
}
Exceptioninthread"main"java.lang.NullPointerException
atStringDemo.main(StringDemo.java:
4)
而如果说现在将代码反过来操作:
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr=null; // 假设是输入的
if("Hello".equals(str)){
System.out.println("条件满足。
");
}
}}
因为字符串常量就是一个匿名对象,匿名对象永远不可能为null,这样的比较才更加的合理。
3.1.4 、String类的两种实例化方式的区别
对于String类的对象存在了两种实例化的操作形式,那么这两种有什么区别,在开发之中应该使用那一种更好呢?
1、 分析直接赋值的情况:
Stringstr="Hello";
发现现在只开辟了一块堆内存空间和一块栈内存空间。
那么随后将代码进行一些修改。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr1="Hello";
Stringstr2="Hello";
Stringstr3="Hello";
System.out.println(str1==str2); //true
System.out.println(str1==str3); //true
System.out.println(str2==str3); //true
}
}
解释:
关于直接赋值操作之中,字符串比较都是相同的原因
在String类进行设计的时候采用了一种称为共享设计模式的概念,在每一个运行的JVM底层存在一个字符串的对象池(ObjectPool),如果用户采用了直接赋值的方式,会将字符串的内容放入到池之中,以供其他继续使用直接赋值方式的String对象使用,如果新声明的字符串内容不再池之中,则会开辟一个新的,继续放到池,以供下次使用。
2、 分析构造方法赋值的情况:
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr=newString("Hello");
System.out.println(str);
}
}
使用构造方法的方式开辟的字符串对象,实际上会开辟两块空间,其中有一块空间将称为垃圾。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr1=newString("Hello");
Stringstr2="Hello"; // 入池
Stringstr3="Hello"; // 使用池对象
System.out.println(str1==str2); //false
System.out.println(str1==str3); //false
System.out.println(str2==str3); //true
}
}
通过上面的程序可以发现,使用构造方法实例化的String对象,不会入池,所以,只能自己使用。
可是在String类之中为了方便操作提供了一种称为手工入池的方法:
publicStringintern()。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr1=newString("Hello").intern();
Stringstr2="Hello"; // 入池
Stringstr3="Hello"; // 使用池对象
System.out.println(str1==str2); //true
System.out.println(str1==str3); //true
System.out.println(str2==str3); //true
}
}
面试题:
请解释String类的两种对象实例化方式的区别?
· 直接赋值:
只开辟一块堆内存空间,字符串的内容可以自动入池,以供下次使用;
· 构造方法:
开辟两块堆内存空间,有一块将成为垃圾,并且不能自动入池,使用intern()手工入池。
在日后的所有开发之中,String对象的实例化永远都采用直接赋值的方式完成。
3.1.5 、字符串的内容一旦声明则不可改变
字符串类的操作特点决定:
字符串不可能去修改里面的内容,所以,如果以后在开发之中有如下程序。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="Hello";
str+="World";
str =str+"!
!
!
";
System.out.println(str);
}
}
通过以上的代码可以发现,字符串内容的更改,实际上改变的是字符串对象的引用过程,并且会伴随有大量的垃圾出现,那么对于以下的代码实际之中应该避免:
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="";
for(intx=0;x<1000;x++){
str+=x;
}
System.out.println(str);
}
}
但是这种代码需要“断开-连接”String对象1000次,会产生大量垃圾,所以不能够去使用。
3.2、String类的常用方法(重点,背)
String类除了之前所介绍的两个方法之外,还存在着大量的其他操作,考虑到String类在实际的工作之中使用非常的广泛,那么就建议大家都背下来,以下所讲解的每一个方法:
记住方法的名称、返回值类型、参数的类型及个数、方法的作用。
以后所有的开发都要和文档挂勾,而且文档不许使中文,因为在所有的Java学习之中,有十几份文档呢。
文档之中会对每一个类进行详细的解释,而一般的解释类的文档的结构:
· 类的基本定义;
· 类的说明;
· 类的主体部分:
|- 类之中的成员(Field);
|- 类中的构造方法(Constructor);
|- 类中的普通方法(Method)。
· 对每一个成员、构造方法、普通方法的作用进行详细说明,包括参数的作用。
3.2.1 、字符串与字符
在很多的语言之中,都强调,字符串由字符数组所组成,那么这一概念在Java的String类之中也有体现。
No.
方法名称
类型
描述
1
publicString(char[]value)
构造
将全部的字符数组内容变为字符串
2
publicString(char[]value,intoffset,intcount)
构造
将部分字符数组变为字符串,offset表示开始点,count表示要操作的长度
3
publiccharcharAt(intindex)
普通
取得指定索引位置上的字符
4
publicchar[]toCharArray()
普通
将字符串转换为字符数组
范例:
验证charAt()方法,这个方法是一个标志性方法
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="helloworld";
charc=str.charAt(7);
System.out.println(c);
}
}
范例:
字符串和字符数组转换,完成一个小写字符串变为大写字符串的操作,小写字母和大写字母差了32
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr="helloworld";
chardata[]=str.toCharArray(); // 字符串变为字符数组
for(intx=0;x System.out.print(data[x]+"、");
data[x]-=32; // 变大写
}
System.out.println();
System.out.println("全部字符数组变为字符串:
"+newString(data));
System.out.println("部分字符数组变为字符串:
"+newString(data,0,5));
}
}
思考题:
现在要求判断一个字符串是否由数字所组成
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
charc='8';
System.out.println(c>='0'&&c<='9');
System.out.println((int)c);
}
}
思路:
将一个字符串首先变为字符数组,而后依次判断字符数组之中的每一个字符是否是数字,如果全是,则返回true,否则返回false。
publicclassStringDemo{
publicstaticvoidmain(Stringargs[]){
Stringstr=" 1a 23";
System.out.println(isNumber(str));
}
publicstaticbooleanisNumber(Stringtemp){
chardata[]=temp.toCharArray(); // 变为字符数组
for(intx=0;x if(data[x]<'0'||data[x]>'9'){
returnfalse; // 不是数字
}
}
returntrue;
}
}
以上的这些操作只是给了一个基本的思路,实际上不可能如此完成的,但是这些基本的程序逻辑应该明白。
3.2.2 、字符串与字节
字符串除了与字符可以互相转换之外,还可以和字节互相转换,操作方法:
No.
方法名称
类型
描述
1
publicString(byte[]bytes)
构造
将全部的字节数组变为字符串