Java面试宝典:核心基础知识精讲
Java面试宝典:核心基础知识精讲
这篇笔记整理了 Java 编程中的核心基础知识,涵盖面向对象编程、常见类与方法区别等内容,适合初学者快速复习或深入理解 Java 的核心概念。以下内容经过精心整理,结构清晰,适合作为博客发布。
1. 面向对象编程(OOP)的核心理念
面向对象编程(OOP)是一种通过将现实世界的事物抽象为类和对象的编程范式。它通过以下三大特性实现代码的模块化与可维护性:
- 封装(Encapsulation):将数据(属性)与操作数据的方法绑定,限制对数据的直接访问,只能通过定义好的接口操作。
- 继承(Inheritance):通过从现有类派生新类,复用父类的属性和方法,减少代码冗余。
- 多态(Polymorphism):允许不同子类对象对同一消息(方法调用)做出不同响应,增强代码灵活性。
示例:
class Animal {void eat() {System.out.println("This animal eats food.");}
}class Dog extends Animal {@Overridevoid eat() {System.out.println("Dog eats bones.");}
}
2. 方法重载(Overloading)与重写(Overriding)的区别
-
重载(Overloading):
- 发生在同一类中。
- 方法名相同,参数列表不同(数量或类型),与返回值无关。
- 编译时多态,静态绑定。
- 示例:
class Calculator {int add(int a, int b) { return a + b; }double add(double a, double b) { return a + b; } }
-
重写(Overriding):
- 发生在子类重写父类方法。
- 方法名、参数列表、返回值类型必须完全相同。
- 子类方法的访问权限不能低于父类,异常范围不能扩大。
- 构造函数不能被重写。
- 示例:
class Animal {void sound() { System.out.println("Some sound"); } } class Cat extends Animal {@Overridevoid sound() { System.out.println("Meow"); } }
3. 接口(Interface)与抽象类(Abstract Class)的对比
特性 | 抽象类 | 接口 |
---|---|---|
继承/实现 | 被子类继承(extends ) | 被类实现(implements ) |
多继承 | 只能继承一个抽象类 | 可实现多个接口 |
构造器 | 可以有构造器(用于子类初始化) | 不能有构造器 |
实例化 | 不能直接实例化 | 不能直接实例化 |
访问修饰符 | 可使用 public 、protected 等 | 方法默认 public |
成员变量 | 可包含普通成员变量 | 只能声明常量(public static final ) |
注意:抽象类的构造器仅在子类实例化时被调用,用于初始化父类部分。
4. 深拷贝与浅拷贝的区别
-
浅拷贝(Shallow Copy):
- 仅拷贝对象本身,对象中的引用类型字段仍指向原内存地址。
- 新旧对象共享引用类型字段,修改可能相互影响。
- 示例:
class Person implements Cloneable {String name;Address address;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();} }
-
深拷贝(Deep Copy):
- 拷贝对象及其所有引用对象,生成完全独立的新对象。
- 修改新对象不会影响原对象。
- 示例:
class Person implements Cloneable {String name;Address address;@Overrideprotected Object clone() throws CloneNotSupportedException {Person p = (Person) super.clone();p.address = (Address) address.clone();return p;} }
5. sleep()
与 wait()
的区别
特性 | sleep() | wait() |
---|---|---|
所属类 | Thread 类 | Object 类 |
锁资源 | 不释放锁 | 释放锁 |
唤醒方式 | 自动唤醒(指定时间后) | 需要 notify() 或 notifyAll() |
使用场景 | 不需要 synchronized | 必须在 synchronized 块中使用 |
注意:调用 wait()
而不使用 synchronized
会抛出 IllegalMonitorStateException
。
synchronized (obj) {obj.wait(); // 释放锁,等待唤醒
}
6. 自动装箱与拆箱:int
与 Integer
- 自动装箱(Autoboxing):将基本数据类型(如
int
)转换为包装类对象(如Integer
)。 - 自动拆箱(Unboxing):将包装类对象转换为基本数据类型。
- 实现原理:通过
Integer.valueOf()
(装箱)和Integer.intValue()
(拆箱)实现,属于编译器的语法糖。 - 用途:便于在集合(如
List<Integer>
)中使用基本类型数据。
int
vs Integer
:
int
是基本数据类型,直接存储值,默认值为0
。Integer
是包装类,引用类型,默认值为null
,需实例化后使用。
List<Integer> list = new ArrayList<>();
list.add(1); // 自动装箱:int -> Integer
int value = list.get(0); // 自动拆箱:Integer -> int
7. ==
与 equals()
的区别
==
:- 基本数据类型:比较值是否相等。
- 引用类型:比较内存地址。
equals()
:- 默认(
Object
类):比较地址(与==
等效)。 - 重写后:通常比较对象内容(例如
String
类重写了equals()
)。
- 默认(
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false(地址不同)
System.out.println(s1.equals(s2)); // true(内容相同)
8. 为什么 String
类使用 final
修饰?
String
不可继承:final
修饰的类不能被继承,防止子类修改其行为。- 效率:
String
是高频使用的类,固定实现避免了重写导致的性能问题。 - 安全性:
String
使用native
方法调用系统 API,禁止继承防止恶意代码注入。
9. StringBuffer
与 StringBuilder
的对比
特性 | StringBuffer | StringBuilder |
---|---|---|
线程安全 | 线程安全(方法加 synchronized ) | 非线程安全 |
性能 | 较慢(因加锁开销) | 较快(无加锁开销) |
使用场景 | 多线程环境 | 单线程环境 |
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" World"); // 高效拼接
10. final
、finally
与 finalize
final
:- 修饰类:不可被继承。
- 修饰方法:不可被重写。
- 修饰变量:不可修改,需初始化为常量。
finally
:- 用于
try-catch
块后,确保代码无论异常与否都执行(常用于资源释放)。
- 用于
finalize
:Object
类方法,垃圾回收前调用,用于清理资源(不推荐使用,建议用try-with-resources
)。
try {// 可能抛出异常的代码
} catch (Exception e) {// 处理异常
} finally {// 释放资源
}
总结
以上内容涵盖了 Java 的核心基础知识,从面向对象编程到常见类与方法的区别。希望这篇笔记能帮助你快速复习或深入理解 Java 编程的精髓!如果有其他问题,欢迎随时探讨。