【总结】Object、String、异常

Object类

1、Object类中包含的主要方法

Object类提供了如下几个常用方法:

*public final native Class<?> getClass(); //返回该对象的运行时类
*  boolean equals(Object obj):判断指定对象与该对象是否相等。
* int hashCode():返回该对象的hashCode值。在默认情况下,Object类的hashCode()方法根据该对象的地址来计算。但很多类都重写了Object类的hashCode()方法,不再根据地址来计算其hashCode()方法值。
* String toString():返回该对象的字符串表示,当程序使用System.out.println()方法输出一个对象,或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的toString()方法返回该对象的字符串表示。Object类的toString()方法返回 运行时类名@十六进制hashCode值 格式的字符串,但很多类都重写了Object类的toString()方法,用于返回可以表述该对象信息的字符串。

在这里插入图片描述
另外,Object类还提供了wait()、notify()、notifyAll()这几个方法,通过这几个方法可以控制线程的暂停和运行。Object类还提供了一个clone()方法,该方法用于帮助其他对象来实现“自我克隆”,所谓“自我克隆”就是得到一个当前对象的副本,而且二者之间完全隔离。由于该方法使用了protected修饰,因此它只能被子类重写或调用。

2、hashCode()和equals()的关系

hashCode()用于获取哈希码(散列码),eauqls()用于比较两个对象是否相等,它们应遵守如下规定:

  • 如果两个对象相等,则它们必须有相同的哈希码。
  • 如果两个对象有相同的哈希码,则它们未必相等。

3、==和equals()有什么区别?

==运算符:

  • 作用于基本数据类型时,是比较两个数值是否相等;
  • 作用于引用数据类型时,是比较两个对象的内存地址是否相同,即判断它们是否为同一个对象;

equals()方法:

  • 没有重写时,Object默认以 == 来实现,即比较两个对象的内存地址是否相同;
  • 进行重写后,一般会按照对象的内容来进行比较,若两个对象内容相同则认为对象相等,否则认为对象不等。

String类

1、String类主要包含哪些方法

String类是Java最常用的API,它包含了大量处理字符串的方法,比较常用的有:

    * char charAt(int index):返回指定索引处的字符;
    * String substring(int beginIndex, int endIndex):从此字符串中截取出一部分子字符串;
    * String[] split(String regex):以指定的规则将此字符串分割成数组;
    * String trim():删除字符串前导和后置的空格;
    * int indexOf(String str):返回子串在此字符串首次出现的索引;
    * int lastIndexOf(String str):返回子串在此字符串最后出现的索引;
    * boolean startsWith(String prefix):判断此字符串是否以指定的前缀开头;
    * boolean endsWith(String suffix):判断此字符串是否以指定的后缀结尾;
    * String toUpperCase():将此字符串中所有的字符大写;
    * String toLowerCase():将此字符串中所有的字符小写;
    * String replaceFirst(String regex, String replacement):用指定字符串替换第一个匹配的子串;
    * String replaceAll(String regex, String replacement):用指定字符串替换所有的匹配的子串。

注意事项

String类的方法太多了,你没必要都记下来,更不需要一一列举。面试时能说出一些常用的方法,表现出对这个类足够的熟悉就可以了。另外,建议你挑几个方法仔细看看源码实现,面试时可以重点说这几个方法。

2、String类包含那些支持正则表达式的方法

在这里插入图片描述

3、 使用字符串时,new和""推荐使用哪种方式?

先看看 “hello” 和 new String(“hello”) 的区别:

  • 当Java程序直接使用 “hello” 的字符串直接量时,JVM将会使用常量池来管理这个字符串;
  • 当使用 new String(“hello”) 时,JVM会先使用常量池来管理 “hello” 直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中。

显然,采用new的方式会多创建一个对象出来,会占用更多的内存,所以一般建议使用直接量的方式创建字符串。

4、字符串相加的实现机制

拼接字符串有很多种方式,其中最常用的有4种,下面列举了这4种方式各自适合的场景。

  • +运算符:如果拼接的都是字符串直接量,则适合使用 + 运算符实现拼接;
  • StringBuilder:如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder;
  • StringBuffer:如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;
  • String类的concat方法:如果只是对两个字符串进行拼接,并且包含变量,则适合使用concat方法;

采用 + 运算符拼接字符串时:

如果拼接的都是字符串直接量,则在编译时编译器会将其直接优化为一个完整的字符串,和你直接写一个完整的字符串是一样的,所以效率非常的高。

如果拼接的字符串中包含变量,则在编译时编译器采用StringBuilder对其进行优化,即自动创建StringBuilder实例并调用其append()方法,将这些字符串拼接在一起,效率也很高。但如果这个拼接操作是在循环中进行的,那么每次循环编译器都会创建一个StringBuilder实例,再去拼接字符串,相当于执行了 new StringBuilder().append(str),所以此时效率很低。

5、String、StringBuffer、StringBuilder有什么区别

  • String是Java中基础且重要的类,并且String也是Immutable类的典型实现,被声明为final class,除了hash这个属性其它属性都声明为final,因为它的不可变性,所以例如拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。
  • StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类,提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上synchronized。但是保证了线程安全是需要性能的代价的。
  • StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

StringBuffer 和 StringBuilder 二者都继承了 AbstractStringBuilder ,底层都是利用可修改的char数组(JDK 9 以后是 byte数组)。

所以如果我们有大量的字符串拼接,如果能预知大小的话最好在new StringBuffer 或者StringBuilder 的时候设置好capacity,避免多次扩容的开销。扩容要抛弃原有数组,还要进行数组拷贝创建新的数组。

异常处理机制

1、异常类的继承体系

所有的异常都是Throwable的子类
在这里插入图片描述
Thorwable有两个直接子类Error和Exception

Error:

在 Java 中只要 Error 发生了就一种结果——退出 JVM,例如 StackOverError

Exception的直接子类:

Exception 的直接子类叫做编译时异常、受控异常、检查异常。它虽然叫做编译时异常,但是它不是发生在编译阶段的异常, 之所以叫做编译时异常是因为编译时异常要求必须在程序编译的阶段就手动的处理,如果不处理这些异常的话,程序无法编译通过。

对于编译时异常有两种手段处理,一是 try catch 捕获,一是 throws 抛出

RuntimeException 的直接子类:

RuntimeException 的直接子类叫做运行时异常、非受控异常、非检查异常。这种异常不要求在程序编译阶段处理,编译也可以通过。比如说除0异常

自定义异常:

JDK 提供的异常不能够满足要求的情况下用户可以自己自定义异常,可以根据实际情况选择继承Exception 或者 RuntimeException 两种形式。

2、异常的处理机制

在Java中,可以按照如下三个步骤处理异常:

1、 捕获异常

将业务代码包裹在try块内部,当业务代码中发生任何异常时,系统都会为此异常创建一个异常对象。创建异常对象之后,JVM会在try块之后寻找可以处理它的catch块,并将异常对象交给这个catch块处理。

2、 处理异常

在catch块中处理异常时,应该先记录日志,便于以后追溯这个异常。然后根据异常的类型、结合当前的业务情况,进行相应的处理。比如,给变量赋予一个默认值、直接返回空值、向外抛出一个新的业务异常交给调用者处理,等等。

3、回收资源

如果业务代码打开了某个资源,比如数据库连接、网络连接、磁盘文件等,则需要在这段业务代码执行完毕后关闭这项资源。并且,无论是否发生异常,都要尝试关闭这项资源。将关闭资源的代码写在finally块内,可以满足这种需求,即无论是否发生异常,finally块内的代码总会被执行。

3、finally在什么条件下会执行,在finally中return会怎么样

不管try块中的代码是否出现异常,也不管哪一个catch块被执行,甚至在try块或catch块中执行了return语句,finally块总会被执行。

注意事项

如果在try块或catch块中使用 System.exit(1); 来退出虚拟机,则finally块将失去执行的机会。但是我们在实际的开发中,重来都不会这样做,所以尽管存在这种导致finally块无法执行的可能,也只是一种可能而已。

在通常情况下,不要在finally块中使用return、throw等导致方法终止的语句,一旦在finally块中使用了return、throw语句,将会导致try块、catch块中的return、throw语句失效。

详细解析

当Java程序执行try块、catch块时遇到了return或throw语句,这两个语句都会导致该方法立即结束,但是系统执行这两个语句并不会结束该方法,而是去寻找该异常处理流程中是否包含finally块,如果没有finally块,程序立即执行return或throw语句,方法终止;如果有finally块,系统立即开始执行finally块。只有当finally块执行完成后,系统才会再次跳回来执行try块、catch块里的return或throw语句;如果finally块里也使用了return或throw等导致方法终止的语句,finally块已经终止了方法,系统将不会跳回去执行try块、catch块里的任何代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值