7.String,StringBuffer,StringBuilder的区别
7.1 String
String时不可变的,一旦String对象被创建以后,包含在这个对象中的字符序列时不可改变的,直到这个对象被销毁。
7.2 StringBuffer
StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer对象被创建后,可以通过StringBuffer对象提供的append(),insert(),等方法改变这个字符串对象的字符序列。
7.3 StringBuilder
StringBuilder对象也可以改变字符序列,基本用法跟StringBuffer相似,两个类的构造器和方法也基本相同,但是StringBuffer是线程安全的,StringBuilder没有线程安全功能,性能略高。
如果要求线程安全(多线程)的场景,就使用StringBuffer,如果对线程安全要求没那么高,要求性能多一点,可以使用StringBuilder。注意:三者都是final类,不允许被继承。
7.4 StringBuffer是如何实现线程安全的?
StringBuffer类中的方法都添加了synchronized关键字,这个方法添加了一个锁,来保证线程安全
8.反射
在运行过程中,对于任何一个类都能获取它的属性和方法,任何一个对象都能调用其方法,这种动态获取信息和动态调用对象,就是反射。
比如当我们new一个student类的对象时,jvm会去本地磁盘找student.class文件并且加载到jvm内存中,同时会自动创建一个class对象,一个类只能有一个class对象。
本质就是得到class对象后,反向获取Student对象的各种信息。
Java获取反射的三种方法:
- 通过new对象实现反射
- 通过路径实现反射
- 通过类名实现反射
9.浅拷贝和深拷贝的区别
主要区别在于拷贝的程度和对原始对象内部结构的影响。
浅拷贝
浅拷贝创建一个对象,如果字段是基本数据类型,则这些字段会被复制到新对象中,如果字段是引用类型,则新对象和原始对象中的引用指向相同对象(因为只复制了引用地址,不复制引用指向的对象);从而导致对新对象进行修改会影响到原始对象。
深拷贝
深拷贝创建一个新的对象,会递归的复制整个对象结构,确保和原始对象之间所有关系都是独立的。
10.抽象类和接口的区别
- 抽象类有构造方法,但接口没有
- 抽象类可以有实例变量,但接口没有实例变量,有常量
- 抽象类只能单继承,但是接口可以实现多个
- 抽象类可以包含非抽象方法,接口在java7之前所有方法都是抽象的,java8之后也可以包含非抽象方法
- 抽象类中的方法可以是任意修饰符,但是接口java8之前都是public,java9支持private
11.Error和Exception有什么区别?
Error:程序无法处理,程序会立即崩溃,jvm停止运行。
Exception:程序可以向上抛出或者捕获。
12.final关键字的作用
- 修饰类:修饰一个类时,表示该类不能被继承。
- 修饰方法:把方法锁定,防止任何继承类修改它的含义,此处需要注意的一点是:因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是在子类中重新定义了新的方法。
- 修饰变量:当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
13.this关键字的作用
可以理解为指向的对象本身的一个指针。
用法大体可以分为三种:
- 当成员方法的成员变量和形参名称重名时,可以用this来区分,表示调用本类中的成员变量。
- 调用成员方法和构造方法。
- 返回类的引用,可以使用return this来返回某个类的引用,this此时就表示类的名称。
14.super关键字的用法
super可以理解为是指向自己父类对象的一个指针,这个父类是指离自己最近的一个父类。
- 调用子类中重写的父类的方法
- 如果父类和子类都有同名的属性,则访问父类的属性
- 从子类构造函数显示地调用父类无参数化构造函数和有参数化构造函数