接口和抽象类的共同点和区别。
回答:接口和抽象类都是面向对象编程中的重要概念,它们都可以被用来实现多态性。接口是一种规范或契约,定义了一组方法和属性,没有实现,需要实现接口的类来具体实现这些方法和属性。抽象类是一种不能被实例化的类,可以包含抽象方法和实现的方法,需要被子类继承并实现抽象方法。接口和抽象类的共同点在于都可以实现多态性,而区别在于抽象类可以包含具体实现的方法,而接口只能包含方法的定义。
重要内容提取:
- 接口和抽象类都可以用来实现多态性。
- 接口只能包含方法的定义,而抽象类可以包含具体实现的方法。
- 都不能被实例化
深拷贝、浅拷贝和引用拷贝的概念及区别。
回答:深拷贝和浅拷贝是两种常见的数据拷贝方式。浅拷贝只是拷贝了对象的引用,新对象和原对象共享同一个内存地址,修改新对象会同时影响原对象。深拷贝则是完全复制了原对象的所有数据,新对象和原对象互相独立,互不影响。引用拷贝是一种特殊的浅拷贝,指的是拷贝对象的引用或指针,而不是拷贝对象本身,新对象和原对象仍然共享同一个内存地址。
重要内容提取:
- 深拷贝和浅拷贝是两种常见的数据拷贝方式。
- 浅拷贝只是拷贝了对象的引用,而深拷贝则是完全复制了原对象的所有数据。
- 引用拷贝是一种特殊的浅拷贝,指的是拷贝对象的引用或指针。
Object 类的常见方法有哪些?
回答:Object 类是所有类的根类,Java 中的其他所有类都是从 Object 类继承而来。Object 类中包含了一些常用的方法,如:
- equals(Object obj):判断两个对象是否相等,未重写为地址值,即判断两个对象是否是同一个对象。
- hashCode():返回对象的哈希码。
- toString():返回对象的字符串表示。
- getClass():返回对象所属类的 Class 对象。
- notify() 和 notifyAll():用于实现线程之间的通信。
- wait() 和 wait(long timeout):使当前线程进入等待状态,直到另一个线程调用 notify() 或 notifyAll() 方法来唤醒它。
== 和 equals() 的区别是什么?
回答:== 是 Java 中的比较运算符,用于判断两个操作数是否相等,它可以用于比较基本数据类型和对象的内存地址。而 equals() 是 Object 类中的方法,用于比较两个对象的内容是否相等,它可以被子类重写以实现具体的对象相等的判断逻辑。
具体区别如下:
- == 比较的是变量之间的值是否相等,而 equals() 比较的是对象之间的内容是否相等。
- 对于基本数据类型,== 比较的是值是否相等,而对于引用类型,== 比较的是对象的内存地址是否相等。
- equals() 方法默认情况下和 == 操作符作用相同,即比较两个对象是否是同一个对象,需要根据实际需求在子类中重写 equals() 方法来实现自定义的对象相等判断逻辑。
重要内容提取:
- == 是比较运算符,用于判断两个操作数是否相等。
- equals() 是 Object 类中的方法,用于比较两个对象的内容是否相等。
- 对于基本数据类型,== 比较的是值是否相等,而对于引用类型,== 比较的是对象的内存地址是否相等。
hashCode() 有什么用?
回答:hashCode() 是 Object 类中的一个方法,用于返回对象的哈希码(散列码),它实际上是根据对象的地址或者对象的数据计算出来的一个数字,具有唯一性。hashCode() 方法的作用是在使用基于哈希表的集合类(如 HashMap、HashSet)时,可以更快地找到对象在集合中的位置,从而提高集合的性能。hashCode() 方法还经常和 equals() 方法一起使用,因为在判断两个对象是否相等时,先判断它们的哈希码是否相等可以提高判断的效率。
重要内容提取:
- hashCode() 是 Object 类中的一个方法,用于返回对象的哈希码(散列码)。
- hashCode() 方法的作用是在使用基于哈希表的集合类时,可以更快地找到对象在集合中的位置,从而提高集合的性能。
- hashCode() 方法经常和 equals() 方法一起使用,先判断哈希码是否相等可以提高判断效率。
- 两个hashcode值相等的两个对象,这两个对象不一定相等,因为hashcode的值是通过hash函数的来,两个对象通过hash函数后可能得到相同的hashcode。
为什么重写 equals() 时必须重写 hashCode() 方法?
回答:在 Java 中,当一个类重写了 equals() 方法时,必须同时重写 hashCode() 方法。这是因为在判断两个对象是否相等时,先判断它们的哈希码是否相等可以提高判断的效率,而哈希码是通过 hashCode() 方法生成的。
**如果两个对象的 equals() 方法相等,但它们的 hashCode() 方法不等,那么它们就不能被正确地存储到基于哈希表的集合中,比如 HashMap、HashSet 等,这会导致这些集合的功能出现问题。
在重写 hashCode() 方法时,需要遵循以下原则:
- 如果两个对象的 equals() 方法返回 true,则它们的 hashCode() 方法必须返回相同的值。
- 如果两个对象的 equals() 方法返回 false,它们的 hashCode() 方法可以返回相同的值,但是不要求相同。
重要内容提取:
- 当一个类重写了 equals() 方法时,必须同时重写 hashCode() 方法。
- 两个对象的 equals() 方法相等,但它们的 hashCode() 方法不等,会导致基于哈希表的集合的功能出现问题。
- 在重写 hashCode() 方法时,需要遵循相等的对象必须返回相同的哈希码这个原则。
介绍一下 String、StringBuilder、StringBuffer ?
回答:
- String:表示字符串,是不可变的,即一旦创建,就无法修改它的内容。每当对 String 对象进行修改时,都会创建一个新的 String 对象。String 适用于那些不经常改变的字符串对象。
- StringBuilder:表示可变的字符序列,可以对它进行修改,每次修改不会创建新的对象,而是对原对象进行修改,因此它的效率比较高。StringBuilder 适用于那些经常改变但长度不会改变的字符串对象。
- StringBuffer:与 StringBuilder 类似,也表示可变的字符序列。不同的是,它是线程安全的,即多个线程同时访问 StringBuffer 对象时,不会出现数据不一致或者其他异常情况。StringBuffer 适用于那些经常改变且长度会改变的字符串对象。
重要内容:
- String 是不可变的,每次修改都会创建一个新的 String 对象;StringBuilder 和 StringBuffer 是可变的,可以对它进行修改,效率比 String 高;
- StringBuilder 和 StringBuffer 都表示可变的字符序列,不同的是 StringBuffer 是线程安全的。
类型 | 特点 | 线程安全性 | 对象操作 |
---|---|---|---|
String | 不可变字符串 | 线程安全 | 操作字符串会创建新的对象 |
StringBuilder | 可变字符串 | 线程不安全 | 操作字符串不会创建新的对象,而是在原有对象上修改 |
StringBuffer | 可变字符串 | 线程安全 | 操作字符串不会创建新的对象,而是在原有对象上修改 |