最新版2025年Java基础知识点总结与面试题解析,助你轻松应对Java面试挑战
面向对象基础
面向对象与面向过程的主要区别
面向对象和面向过程的区别在于问题解决的方式:
- 面向过程通过将问题拆分为一个个方法来解决,依靠方法的执行来完成任务。
- 面向对象则是先抽象出对象,并通过对象来调用方法解决问题。
此外,面向对象的程序通常更易于维护、重用和扩展。
成员变量与局部变量的区别
- 语法形式:成员变量属于类,而局部变量在方法或代码块中定义。成员变量可以被
public
,private
,static
等修饰符修饰,而局部变量不能被访问控制修饰符及static
修饰。 - 存储方式:成员变量存放在堆内存中,而局部变量存放在栈内存中。若成员变量被
static
修饰,则属于类,否则属于实例。 - 生存时间:成员变量伴随对象的创建而存在,局部变量在方法调用时生成,方法结束时消失。
- 默认值:若成员变量未赋值,则会自动赋类型的默认值(被
final
修饰的成员变量需显式赋值),而局部变量则不会自动赋值。
创建对象时使用的运算符及对象实体与对象引用的不同
创建对象时使用 new
运算符,它会在堆内存中创建对象实例,而对象引用则存放在栈内存中。一个对象引用可以指向一个对象,也可以不指向任何对象;反之,一个对象可以被多个引用指向。
对象相等与引用相等的区别
- 对象相等主要比较内存中存放的内容是否一致。
- 引用相等比较的是对象指向的内存地址是否相同。
类的构造方法的作用
构造方法是特殊的方法,主要用于完成对象的初始化工作。
类未声明构造方法的情况下程序是否能正常执行?
如果类没有声明构造方法,程序仍可正常执行,因为Java会默认提供一个无参数的构造方法。若自定义构造方法,默认的无参数构造方法将不再存在。因此,在重载构造方法时,建议还要写出无参数构造方法以避免潜在问题。
构造方法的特点及是否可被重写
构造方法的特点包括:
- 名字与类名相同。
- 没有返回值,且不能用
void
声明。 - 对象创建时自动执行,无需显式调用。
构造方法不能被重写,但可以重载,因此一个类中可以包含多个构造函数。
面向对象的三大特征
封装
封装是将对象内部的状态信息隐藏,使外部无法直接访问。可以通过提供的访问方法来操作属性。例如,空调的内部零件是封装的,控制空调的遥控器相当于访问方法。
public class Student {
private int id; // id属性私有化
private String name; // name属性私有化
// 获取id的方法
public int getId() {
return id;
}
// 设置id的方法
public void setId(int id) {
this.id = id;
}
// 获取name的方法
public String getName() {
return name;
}
// 设置name的方法
public void setName(String name) {
this.name = name;
}
}
继承
继承允许新类基于现存类创建,并能增加新的特性或功能。例如,小明、小红和小李同学共享学生的特性(如班级、学号),同时每个学生也有其独特性。通过继承,能够快速创建新类,提高代码的重用性,增强程序的可维护性。
记住以下三点关于继承:
- 子类继承父类的所有属性和方法,但无法访问父类的私有属性和方法。
- 子类可以添加自己的属性和方法。
- 子类可以重写父类的方法。
多态
多态表示一个对象可以有多种状态,具体表现为父类的引用指向子类的实例。
多态的特点:
- 对象类型和引用类型之间存在继承或实现关系。
- 方法调用的具体实现必须在程序运行期间确定。
- 多态不能调用仅存在于子类中的方法。
- 若子类重写了父类的方法,实际执行的是子类的实现。
接口与抽象类的共同点和区别
共同点:
- 均不能被实例化。
- 均可以包含抽象方法。
- Java 8 之后,均可以定义默认实现的方法。
区别:
- 接口主要用于约束行为,抽象类强调代码复用。
- 一个类只能继承一个抽象类,但可以实现多个接口。
- 接口的成员变量只能是
public static final
,而抽象类的成员变量可以具有不同的访问修饰符。
深拷贝与浅拷贝的区别及引用拷贝的概念
- 浅拷贝:在堆上创建新对象,若原对象内部属性为引用类型,则仅复制引用地址,导致拷贝对象与原对象共享同一内部对象。
- 深拷贝:完全复制整个对象,包括内部对象。
引用拷贝:不同的引用指向同一个对象。
示例代码片段展示了如何实现浅拷贝和深拷贝。
浅拷贝示例:
public class Address implements Cloneable {
private String name;
@Override
public Address clone() {
try {
return (Address) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
public class Person implements Cloneable {
private Address address;
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
深拷贝示例:
@Override
public Person clone() {
try {
Person person = (Person) super.clone();
person.setAddress(person.getAddress().clone());
return person;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
Java 常见类
Object 类的常见方法
Object
类是所有类的父类,提供了11个基本方法,如 getClass()
, hashCode()
, equals()
, clone()
, 和 toString()
。
==
与 equals()
方法的区别
- 对于基本数据类型,
==
比较值。 - 对于引用数据类型,
==
比较内存地址。 equals()
方法用于判断两个对象的内容是否相等。
hashCode()
方法的作用
hashCode()
获取一个对象的哈希码,常用于哈希表的索引位置。为了提高效率,hashCode()
与 equals()
一起使用,以更快地判断对象是否相等。
为什么重写 equals()
时必须重写 hashCode()
因为相等的对象必须具有相同的哈希码,若只重写 equals()
而不重写 hashCode()
可能导致哈希冲突,影响对象在集合中的存储和检索。
String
、StringBuffer
、StringBuilder
的区别
- 可变性:
String
不可变,StringBuffer
和StringBuilder
可变。 - 线程安全性:
StringBuffer
是线程安全的,StringBuilder
不安全。 - 性能:
StringBuilder
性能优于StringBuffer
。
字符串不可变的原因
String
的数组为 final
,并且没有修改方法。String
类被声明为 final
,不允许被继承。
字符串拼接时使用 +
还是 StringBuilder
在循环中使用 +
进行字符串拼接会创建多个对象,推荐使用 StringBuilder
以提高性能。
字符串常量池的作用
字符串常量池用于避免字符串的重复创建,提高性能和减少内存消耗。