🌟个人主页:时间会证明一切.
String 为什么不可变
- String类被声明为final,这意味着它不能被继承。那么他里面的方法就是没办法被覆盖的。
- 用final修饰字符串内容的char[](从JDK 1.9开始,char[]变成了byte[]),由于该数组被声明为final,一旦数组被初始化,就不能再指向其他数组。
- String类没有提供用于修改字符串内容的公共方法。例如,没有提供用于追加、删除或修改字符的方法。如果需要对字符串进行修改,会创建一个新的String对象。
Java 中异常分哪两类,有什么区别?
Java中的异常,主要可以分为两大类,即受检异常(checked exception)和 非受检异常(unchecked exception)
对于受检异常来说,如果一个方法在声明的过程中证明了其要有受检异常抛出:
public void test() throws Exception{}
那么,当我们在程序中调用他的时候,一定要对该异常进行处理(捕获或者向上抛出),否则是无法编译通过的。这是一种强制规范。
这种异常在IO操作中比较多。比如FileNotFoundException ,当我们使用IO流处理一个文件的时候,有一种特殊情况,就是文件不存在,所以,在文件处理的接口定义时他会显示抛出FileNotFoundException,起目的就是告诉这个方法的调用者,我这个方法不保证一定可以成功,是有可能找不到对应的文件的,你要明确的对这种情况做特殊处理哦。
所以说,当我们希望我们的方法调用者,明确的处理一些特殊情况的时候,就应该使用受检异常。
对于非受检异常来说,一般是运行时异常,继承自RuntimeException。在编写代码的时候,不需要显式的捕获,但是如果不捕获,在运行期如果发生异常就会中断程序的执行。
这种异常一般可以理解为是代码原因导致的。比如发生空指针、数组越界等。所以,只要代码写的没问题,这些异常都是可以避免的。也就不需要我们显示的进行处理。
试想一下,如果你要对所有可能发生空指针的地方做异常处理的话,那相当于你的所有代码都需要做这件事。
接口和抽象类的区别,如何选择?
接口和抽象类的区别其实挺多的。比如以下这些:
方法定义:接口和抽象类,最明显的区别就是接口只是定义了一些方法而已,在不考虑Java8中default方法情况下,接口中只有抽象方法,是没有实现的代码的。(Java8中可以有默认方法)
修饰符:抽象类中的修饰符可以有public、protected和private和这些修饰符,而接口中默认修饰符是public。不可以使用其它修饰符。(接口中,如果定义了成员变量,还必须要初始化)
构造器:抽象类可以有构造器。接口不能有构造器。
继承和实现:接口可以被实现,抽象类可以被继承。
单继承,多实现:一个类可以实现多个接口,但只能继承一个抽象类。接口支持多重继承,即一个接口可以继承多个其他接口。
职责不同:接口和抽象类的职责不一样。接口主要用于制定规范,因为我们提倡也经常使用的都是面向接口编程。而抽象类主要目的是为了复用,比较典型的就是模板方法模式。
所以当我们想要定义标准、规范的时候,就使用接口。当我们想要复用代码的时候,就使用抽象类。
一般在实际开发中,我们会先把接口暴露给外部,然后在业务代码中实现接口。如果多个实现类中有相同可复用的代码,则在接口和实现类中间加一层抽象类,将公用部分代码抽出到抽象类中。可以参考下模板方法模式,这是一个很好的理解接口、抽象类和实现类之间关系的设计模式。