Object类、String类、字符串、异常

快捷键:再IDEA中查看JDK的源代码,ctrl+7;查看一个类的所有方法或者属性,alt+7;快捷生成toString方法,alt+insert(enter)

一、Object类(Object类是参数的最高统一类型)

 1.1、Java.lang.Object类是Java中所有类的共同父类,不需要显示extends,只要是Java的类,Object都是他们的父类(好处:方便与参数统一化)。因此方法参数若需要接收所以类的对象,可以使用Object类来接收。

1.2、除了可以接收所有类的对象以外(因为Object是java中所有类的默认父类),object还可以接收所有的引用数据类型(接口和数组)。

2.1、toString方法,获取一个对象的具体信息

3.1、equals:对象比较相等使用equals方法!!!在引用数据类型进行内容比较时,使用equals方法!!!

3.2千万注意,“==”操作符在进行字符串对象比较和包装类对象比较的时候的陷阱!!!!!!

在Java中,“==”操作符返回布尔值,比较两个变量的“数值”是否相等(对于基本数据类型,变量存储的就是具体的内容值;对于引用数据类型。存储的是对象的地址,“==”实际上是在比较他俩的地址值是否相等,不会比较内容。)。

3.3、只要进行的是对象的内容比较,千万不能使用“==”,统一使用equals方法。

面试题:请说出“==”和equals的区别

1.“==”比较的是两个变量的数值是否相等,对于基本数据类型,比较的是具体保存的数值,对于引用数据类型比较的是两个引用类型的地址是否相同。

2.equals方法是Object类的默认方法,自定义类型覆写equals方法可以按照属性值来比较两个对象的内容是否相等,==比较的是地址,equals比较的是两个对象的属性值是否相同。

二、String类

1、Java中String是引用数据类型

关于字符串的对象创建方法,常用的四种方式有:

a、使用字符串的常量直接赋值

b、通过字符串的常量的构造方法

c、通过字符数组进行构造

d、调用字符串的valueOf方法

面试题:为何String类型被final修饰?

String是引用数据类型,因此String只是保存了字符串对象的地址,被final修饰的类不能被继承,没有子类,限制了String类被扩展或者修改的可能性,这样的话,对于String这个类型就不存在多态,保证所有使用JDK的使用者,大家用的String都是相同的版本,使用的方法也都完全一致。

例:若字符串的引用为null

String str=null;

boolean isEmpty=str.isEmpty();//is.Empty这个方法判断当前字符串对象的长度是否为0;

A、false

B、true

C、编译出错

答:编译出错,只要是通过null值“.”操作任何成员方法,一定都是空指针异常!

正确使用为:

String str=null;

boolean ret=false;

if(str==null || str.isEmpty()){

     ret=true;

}

三、字符串

1、两个字符串对象的比较

“”括起来都是字符串的字面量,都是字符串的对象!

如:System.out.println(“hello”.isEmpty());

1.1、通过==比较(比较的是两个字符串的地址,不看内容)

1.2、通过equals方法来比较两个字符串对象的内容是否相等(大小写敏感)(返回Boolean)

1.3、通过equalslgnoreCase比较两个字符串对象的内容是否相等(大小写不敏感)(返回Boolean)

1.4、通过comparaTo方法来比较两个字符串对象的大小关系(返回int(根据ASCII码值来计算))

comparaTo方法的比较规则:

a、首先按照两个字符串的字典序大小比较,若出现不相等的字符,直接返回这两个字符的大小查值(字符编码差值)

“Hello”

“hello”

“H”-“h”=32;

b、若前k个字符相等(k是两个字符长度的最小值),返回长度差。

“Hello”(S1)

“Hello123”(S2)

System.out.println(S1.comparaTo(S5));

返回-3;

2、字符串常用操作

字符串内部也是使用字符数组来存储内容的 char[] value

字符串也是线性表的一种

JDK中char的包装类character中有一个静态方法,判断字符是否是数字字符

字符串内容的查找

2.1在字符串中查找指定的字符

char charAt(int index);返回字符串中指定索引index位置的字符

3、字符串查找

contains---->判断字符串中是否有指定的子串,若有返回true,否则返回flase。

4、字符串转换

4.1、其他类型转为字符串对象valueOf方法,可以接受所有参数

String S1=String.valueOf(123)---->123

4.2、大小写转换(只限于字母字符串,包含数字或者中文没啥效果)

String S1="hello";

S1=S1.toUpperCase();---->HELLO '

String S1="HELLO";

S1=S1.toLOwerCase();---->hello; 

4.3***字符串转为数组***

a、转为字符数组  toCharArray();

String S1="hello";

char[] data=S1.toCharArray();------>[h,e,l,l,o]

b、转为字节数组getBytes(可以传入指定的字符编码)

4.4、格式化字符串

//类似于c的printf,但是支持正则表达式

String.format();

String str=String.format("%d-%d-%d,2022,9,12");---->2022-3-12

4.5、字符串的替换

String replaceAll(String regex,String replacement);//替换所有指定的内容

String replaceFirst(String regex,String replacement);//替换首个内容

4.6、字符串拆分(将一个字符串按照指定的格式拆分成字符串数组!)

String[] split(String regex);//将字符串全部拆分

String[] split(String regex,int limit);//将字符串以指定额格式,拆分为limit组

当调用split碰到某些特殊字符无法正确拆分时,需要用到转义字符。

例:String str=“192.168.12.14”;

String[] data=str.split(“\\.”);

4.7、*****字符串的截取方法******

String substring(int beginlndex);//从指定位置开始截取到字符串结尾,保留开始字符

String substring(int beginlndex,int endindex);//截取部分内容,左闭右开,保留开始字符,不保留结束字符。

4.8、字符串的trim()方法

trim()方法:去掉字符串的左右两端的空格(制表符、换行符),中间保留。

例:“ hello world ”----->hello world;

5、关于字符串常量的理解

5.1、采用直接赋值类似String str=“字符串字面量”的方式创建字符串对象,会使用字符串的常量池(只有直接赋值的方式会用到常量池)。若该对象第一次使用,就在堆中开辟新空间,产生新对象,产生之后将该对象置入字符串的常量池,当下次再次使用该对象时(还是采用直接赋值的方式),若常量池中已有该内容的字符串,直接引用常量池中的对象,不再创建字符串(即不再产生新的对象)。

例:String str=“hello”;

String str1=“hello”;-------->str==str1----->true;

6、字符串的不可变性

6.1、当一个字符串的对象产生之后,他的内容就无法修改,这称之为字符串对象的不可变性。

6.2、这里指的不可变指的是字符串的对象内容不能修改,而不是字符串的引用。

6.3、经典面试题1:你怎么理解字符串对象不可变,是如何做到内容无法修改的?结合String的源码来分析一下为什么唯独字符串对象的内容无法修改?

之所以字符串对象的内容不可变,本质在于private封装,在String类中,将value数组完全封装,对外没有提供任何获取或者修改该value内容的方法!,因此字符串对象一旦产生,内容就无法修改。(final修饰引用数据类型的变量,不能改的是这个引用的指向不变,至于引用的对象内部如何变化,这是可以的!!)

6.4、经典面试题2: 字符串的subString截取字符串,替换replace等等方法看起来这不都是在修改字符串对象内容吗???

6.5、String类上一把刀,它的对象不可变。因此String类的内部提供的所有设计字符串修改的方法,都会产生新的字符串对象,并不会影响原字符串对象!

6.6、在JAVA中需要反复修改字符串的内容,推荐使用Java提供的StringBuilder(90%都是,线程不安全,效率高)或StringBuffer(10%是,需要保证线程安全的场景)(StringBuild对象上的所有操作都是在原来对象的内部进行修改的!可变的!)

以String Build为例,经常使用到这两个类之间的转换:

String-->StringBuilder

a、通过StringBuilder类的构造方法

例:String str=“abc”;

StringBuilder sb=new StringBuilder(str);

b、通过StringBuilder类的append方法

例:String str=“abc”;

StringBuilder sb1=new StringBuilder();

sb1.append(str);

c、StringBuilder对象->String对象调用toString方法

例:String str=“abc”;

StringBuilder sb1=new StringBuilder();

//abc

sb1.append(str);

//abc123

sb1.append(123);

String ret=sb1.toString();

System.out.printfln(ret);

经典面试题:String、SreingBuilder、StringBuffer类有哪些区别?

1、string的内容无法修改,SreingBuilder、StringBuffer的对象内容可以修改,因此我们一般在字符串对象频繁使用修改的时候使用SreingBuilder或者StringBuffer类。

2、SreingBuilder和StringBuffer的用法完全一致,SreingBuffer采用同步处理,线程安全,效率较低;SreingBuilder采用异步处理,线程不安全,效率较高,开发中若不考虑线程安全问题,一般推荐使用SreingBuilder类进行字符串中内容的修改!!!(javac编译器其实也会将String+=操作优化为SreingBuilder类的append操作)

7、字符串的intern方法 

调用这个intern方法,会将产生的字符串对象置入常量池(若不存在则置入),若常量已存在该对象中,则返回常量中的字符串对象引用。(为了避免歧义,每次调用intern方法之后一定要接受返回值---->str=str.intern();)

8、关于字符串常量池

a、存储一系列的字符串对象,当字符串常量第一次出现,且常量池中没有该值的字符串对象,就会将该对象置入常量池。

b、若采用直接赋值的方式声明字符串引用,若常量中存在该对象,则直接返回常量池的字符串对象,不会创建新对象。

c、关于intern方法,尝试将当前字符串对象置入常量池,若常量池没有该值,则将当前对象置入常量池,若常量池已经包含了该值的对象,则不会将该对象置入常量池,intern方法直接返回常量池对于的对象。

四、异常

1.1、在Java中,将程序执行过程中发生的一些不正常行为称之为“异常”,编译阶段语法错误不是异常!

2、两大最常见的异常

a、越界异常(IndexOutOfBoundsException)

b、NPE(空指针异常,NullPointerException)

例:str=null;

System.out.println(str.length());

3.1异常的继承体系(所有异常的子类都is a异常)

 一旦是发生error异常,程序一定会退出,程序员别无他法只能检查问题出现的地方并修改。

 4、try.....catch的使用

4.1、catch代码块只会捕捉相应的异常,若try中出现的异常不是当前catch对应的异常,程序还是会中断。(此时可以考虑使用多个catch)

4.2、若在某段代码块中可能会产生多个异常的时候,推荐使用多个catch代码块来捕捉不同类型的异常类型,也有程序员使用父类来接受所有的异常!!(不过这种写法不推荐使用,出现的异常不知道具体产生的原因)

4.3、例:假如出现两个运算异常,是否会被捕捉两次?输出两次异常呢?

不会!!异常的捕捉只会出现一次。(如try中第一次检测到出现异常的代码后,剩下的代码就不再执行,直接转到catch)

4.4、异常处理流程

try{     (若异常发生,try剩下代码不再执行,去catch块中匹配具体的异常类)

  //所有可能产生异常的代码块

}catch(要捕捉的异常类型){   (若没有相关的catch块与出现的异常匹配,程序退出,执行剩下代码块)

//出现异常之后执行的代码

}finally{

//无论是否发生异常,一定会执行的代码块

}

补充:捕获到相关异常之后打印异常产生错误的原因以及出现的位置,可以调用异常对象的printStackTrace方法

System.err.println();---->错误输出

4.5、关于catch的代码块的特殊说明

a、若多个catch代码块出现父子关系,则一定是子类写在前,父类写在后。顺序不能改变。

5、异常体系

a、受查异常:程序编译阶段必须显示进行异常处理的异常类型,除了非受查异常以外全部都是受查异常,比如IOException与SQLException都是受查异常。

b、非受查异常:程序编译阶段可以不处理异常,在运行的阶段输出异常Error与RuntimeException以及子类都属于非受查异常,NPE,越界异常,类型转换异常。

6、在异常中finally关键字的特殊情况

6.1、无论是否发生异常,并且这个异常有没有正确被捕捉到,final代码块都会被执行(一般资源的关闭操作,网络的关闭操作都放在final代码块中处理)

6.2、finally中包含return语句的特殊情况:1、finally中的return会覆盖try或者catch的返回值!2、一般开发中,finally只是进行资源操作不涉及返回值。

7.异常的处理流程

1.1、本方法的内部产生异常,当前方法就处理。

1.2、本方法的内部产生异常,自己不处理,将异常对象沿着方法的调用链向上传递!

2.1、有两组关键字和异常抛出有关

a、throws用在方法声明上,明确表示当前方法可能产生的异常,但当前方法不处理,若异常产生,将异常抛出给调用者。(主方法处理异常,主方法的内部的其余代码正常运行结束,若主方法不处理异常,则该异常就会抛回JVM,程序退出)(throws也可以同时抛出多个异常,若抛出的异常有父子关系,只需要声明父类异常即可)

b、throw用在方法的内部,表示人为进行异常对象的产生,一般和自定义异常搭配使用。(按照Java语法来说,此处没有任何异常,但是我们根据具体的业务场景,可以规定在某些场景下,抛出相关的异常!这就要使用throw关键字,人为进行异常对象的产生!)

8、自定义异常的两步走

1、只需要继承Exception(受查)或者RuntimeException(非受查)===>必须显示处理异常的继承Exception,可以不显示处理,就继承RuntimeException

2、实现一个带String的有参构造,String方法参数,就是异常的原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值