1.你是怎样理解OOP面向对象
面向对象是利用语言将现实事物进行抽象。它有以下特征:
- 封装:把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口
- 继承:从已有类得到继承信息创建新的类
- 多态:利用重载和重写实现多态,使的不同子类对于同一消息作出不同的响应
2.重载与重写区别
- 重载是发生在本类的,重写是发生在父类与子类的
- 重载重写的方法名相同,但重载参数列表必须不同,重写参数列表必须相同
- 重载可以有不同的返回类型,重写必须与父类相同,且重写的访问权限不得低于父类被重写的方法的访问权限
- 构造方法可以重载,不可以重写
3.接口和抽象类的区别
- 抽象类可以有成员变量和非抽象方法,可以有方法体和构造方法;接口不可以有,只能声明常量
- 抽象类要被子类继承,接口要被类实现
- 抽象类只能单继承,接口可以多继承接口
- 抽象类的方法可以有除private之外的修饰符,接口必须是public
4.深拷贝和浅拷贝的理解
- 对于基本数据类型(byte,short,int,long,float,double,char,boolean),两者都是直接复制值
- 对于引用数据类型,浅拷贝是拷贝引用对象的内存地址,拷贝和被拷贝均指向同一个对象;深拷贝是将引用地址所指向的对象复制,指向不同的对象
5.sleep和wait区别
- sleep是Thread类的方法,wait是Object类的方法
- sleep和wait都释放CPU,但sleep不释放锁,wait会释放锁资源
- sleep(1000)和wait(1000)都是超过1秒后唤醒;不同的是,wait()会等待被notify()或者notifyall()唤醒
- 使用wait时应与synchronized一起使用,否则会抛出IllegalMonitorStateException异常(illegal)
6.什么是自动拆箱装箱
基本数据类型,如byte,short,int,long,float,double,char,boolean,不具备对象的特征,不能调用方法
- 拆箱:将包装类对象转换为基本数据类型
- 装箱:将基本数据类型转化为包装类对象
在Java集合中,list集合如果想放整数时,是不能放基本数据类型int的,只能放对象integer。因为Java的创建者决定以最小侵入的方式实现泛型类型:所有具体类型列表< T>实际上被编译为(二进制等价物)List< Object>,而基本数据类型是不能和Object转换的,但类(如Integer
、Double
等)是泛型类型的一部分,它们实现了Comparable
接口,并且重载了equals
、hashCode
等方法,使得它们可以被用作集合中的元素。
实现原理:调用包装类的ValueOf()实现自动装箱,调用xxxValue()实现自动拆箱。
例:
Integer i = Integer.valueOf(42);// 自动装箱
int j = i.intValue();// 自动拆箱,也可以写成int j=i;
7.==与equal区别
- ==
- 如果是基本数据类型,那么比较的是两个数据的值是否相等
- 如果是引用数据,那么比较的是两个数据的地址是否相等(是否指向同一内存块)
- equal
- 是Object类的方法,默认实现就是==
- 如果没重写,那么是比较两个对象的地址值
- 重写后,往往是比较对象的属性的内容是否相同,例如String
可以查看String重写的equal方法的源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
8.String类能被继承吗?为什么用final修饰
不能被继承。因为String被final修饰了
- String是最常用的对象之一,为了效率,禁止继承和重写
- 为了安全。String类中有 native关键字修饰的调用系统级别的本地方法,调用了 操作系统的API,如果方法可以重写,可能被植入恶意代码,破坏程序。
9.final和finally、finalize区别
- final:修饰变量则为常量,修饰类则不可派生新的子类,修饰方法则不可被重写(但还是能被继承和重载的)
public class Person {
private String name;
private int age;
private String sex;
final public void work(){ //final 修饰的最终方法 可以被子类继承,但不能被重写
System.out.println("a person can do work");
}
final public void work(int age){ //重载一个final类
System.out.println("a person can do another work");
}
public void eat(){ //普通方法 可以被子类继承、重写
System.out.println("a person need to eat");
}
public static void sleep(){ //静态方法 可以被继承
System.out.println("a person need to sleep");
}
}
public class Man extends Person{
public void eat(){
System.out.println("the man also need do eat");
}
public static void sleep(){
System.out.println("the man also need to sleep");
}
}
import java.time.LocalDateTime;
public class Main {
public static void main(String[] args) {
Person man=new Man();
man.work();
}
}
结果:
- finally:通常放在 try…catch的后面构造最终执行代码块,这就意味着程序无论正 常执行还是发生异常,这里的代码只要 JVM不关闭都能执行,可以将释放外部资源的代码写在 finally块中
- finalize:Object 类中定义的方法,Java中允许使用 finalize() 方法在垃圾收集器 将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销 毁对象时调用的,通过重写 finalize() 方法可以整理系统资源或者执行其他清理工 作
10.StringBuffer和StringBuilder的区别
- StringBuffer是线程安全的,因为它的大部分方法都采用了synchronized修饰,而StringBuilder没用被synchronized修饰,可以被看成是线程不安全的
- StringBuilder在单线程程序中,比StringBuffer更加高效(不需要判断是否拥有锁)
- 两者在方法和功能上是完全等价的