文章目录
- 1.面向对象三大特征是什么,用例子解释一下
- 2.重载和重写的区别是什么?
- 3.抽象类和普通类的区别是什么?
- 4.抽象类能加final修饰吗?
- 5.解释一下静态变量和静态方法
- 6.抽象类和接口的区别是什么?
- 7.浅拷贝和深拷贝的区别是什么?
- 8.什么是反射,反射的作用是什么?
- 9.==和equals区别是什么?
- 10.hashcode和equals的关系是什么?
- [11.String StringBuilder StringBuffer 区别](#11.String StringBuilder StringBuffer 区别)
1.面向对象三大特征是什么,用例子解释一下
面向对象三大特征是:封装、继承、多态。
- 封装:对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。
定义一台基础车,我们把 fuel(油量)藏起来,不让外部直接修改,只能通过 refuel(加油)方法操作。 - 继承:是一种子类可以共享父类数据结构与方法的机制,实现代码复用。
造一台电动车,继承车的所有的非私有成员和功能(如drive())。 - 多态:多种形态,父类定义一个动作,子类根据自己的特点去实现它。当你调用这个动作时,程序会根据"对象到底是谁"来自动执行对应的代码。
电动车的drive重写和父类不一样
2.重载和重写的区别是什么?
- 重载:指的是在同一个类内,可以有很多同名方法,他们具有不同的参数列表(参数类型,数量,顺序的不同),编译器会根据调用时所需的不同参数类型来选择对应方法。
- 重写:指的是子类重写父类的方法,方法名、参数列表、返回值都要和父类一样,使用@override注解表面为重写父类方法。
3.抽象类和普通类的区别是什么?
- 实例化:普通类可以实例化对象,抽象类不能,只能通过继承
- 方法实现:普通类要有实现(空的方法也算空实现public void stop() { }),抽象类可以有也可以没有实现(public void stop();)。
4.抽象类能加final修饰吗?
不能,抽象类是用来被继承的,而final是防止类被继承和方法被重写的。
5.解释一下静态变量和静态方法
- 静态变量(类变量):在类中使用static关键字声明的变量如static int a=0;,它属于类而不是其他对象。
- 共享性:所有实例共享静态变量,一个实例修改静态变量,其余实例也可看见。
- 初始化:静态变量在类加载的时候初始化,只会对它分配一次内存。
- 访问方式:静态变量可以直接通过类名访问。
- 静态方法:在类中使用static关键字声明的方法如public static void a(),一样属于类,不需要new对象就可以用。
- 无实例依赖:调用静态方法的时候,可能没有类任何一个实例存在。
- 多态性:不能被重写。
- 访问静态成员:类.静态方法,可以调用其他静态变量和静态方法。
6.抽象类和接口的区别是什么?
抽象类强调是什么,A是B的一种,鸟(抽象类)所有的鸟都有翅膀,只能单继承。
接口强调能做什么,A具备某种能力。会飞(接口)鸟会飞,飞机会分,多实现。
7.浅拷贝和深拷贝的区别是什么?
- 浅拷贝 (Shallow Copy)
- 做法:创建一个新对象,然后将原始对象的属性值精确拷贝一份。
- 结果:
如果属性是基本类型(如 int, double),拷贝的就是具体的值。
如果属性是引用类型(如 Array, Object),拷贝的就是内存地址。 - 影响:原始对象和拷贝对象共享同一个内部对象。如果你修改了拷贝对象里的某个子对象,原对象也会跟着变。
- 深拷贝 (Deep Copy)
-
做法:创建一个新对象,不仅拷贝基本类型,连同原对象引用的所有子对象也会递归地重新创建一份。
-
结果:两个对象在内存中完全独立。
-
影响:修改其中任何一个对象,都不会对另一个产生影响。
- 形象类比:共享文档 vs 副本文件
浅拷贝:就像你发给别人一个腾讯文档的"共享链接"。虽然你们有两个链接,但点进去改的是同一个文档。
深拷贝:就像你把一个 Word 文档另存为副本发给别人。他改他的,你改你的,互不干扰。 - 使用:默认的 Object.clone() 方法实现的是浅拷贝,深拷贝要重写clone递归克隆引用类型字段或把对象转成 JSON 字符串,再转回对象
8.什么是反射,反射的作用是什么?
反射:在运行状态中,对于任意一个类都能知道类里面的所有属性和方法,对于任意一个对象都能调用它的方法和属性。
让程序在运行时通过"查字典"(读字节码)来动态决定要做什么,从而实现代码逻辑与具体实现(如数据库驱动、插件)的完美解耦。通过改配置文件(yaml)不需要改代码不需要重新编译。
- JDBC 驱动加载
Java
Class.forName("com.mysql.cj.jdbc.Driver");
为什么要用反射?
如果直接写 new Driver(),你的代码就和 MySQL 这种特定的数据库强绑定了。如果你想换成 Oracle,就得改代码、重新编译。
反射怎么做?
通过 Class.forName 传入一个字符串。程序运行到这里时,才会去寻找并加载这个驱动类。这实现了代码与具体数据库驱动的解耦。
-
IDE 的代码提示
当你输入 user. 时,IDEA 瞬间弹出的方法列表是怎么来的?
反射体现:
IDEA 内部通过反射机制实时读取了 User 类对应的 .class 文件,把里面定义的 public 方法全部提取出来展示给你。
-
Spring 框架的 IOC(控制反转):自动装配
你在 Spring Boot 中写下 @Autowired 或 @Service 时,反射就在背后疯狂工作。
场景:你定义了一个 UserService,并在 Controller 中引用它。你并没有写 userService = new UserServiceImpl()。
反射体现:
扫描:Spring 启动时,利用反射读取包下所有类的信息。
识别:发现类上有 @Service 注解,就用反射调用构造函数创建一个实例存入"容器"。
注入:发现属性上有 @Autowired,就用反射拿到该属性的 Field 对象,然后调用 field.set(target, value) 把实例塞进去。
9.==和equals区别是什么?
==:基本数据类型就比数值等不等,比对象就比地址等不等。
equals:默认也是比地址,但很多类(String、Integer)重写了,变成比内容是不是一样的
java
@Override
public boolean equals(Object o) {
// 1. 自反性:如果是同一个实例,直接返回 true
if (this == o) return true;
// 2. 判空与类型检查:如果对象为空,或者类型不匹配,直接返回 false
if (o == null || getClass() != o.getClass()) return false;
// 3. 强转:将 Object 转为当前类类型
User user = (User) o;
// 4. 字段比较:比较核心字段(如 id 或 唯一标识)
// 使用 Objects.equals 可以避免空指针异常
return Objects.equals(id, user.id) &&
Objects.equals(username, user.username);
}
10.hashcode和equals的关系是什么?
equals 是最终的审判,而 hashCode 是初步的筛选。
- Java 官方对这两个方法有一套必须遵守的约定:
如果两个对象调用 equals() 返回 true,那么它们的 hashCode 必须相等。
如果两个对象的 hashCode 相等,它们调用 equals() 不一定返回 true。(这叫"哈希碰撞")
如果两个对象的 hashCode 不相等,它们调用 equals() 一定返回 false。 - 想象你要在 HashMap 里找一个 Key:
第一步:找桶(hashCode)
HashMap 先根据 Key 的 hashCode 算出它在哪个"桶"里。如果两个对象的 hashCode 不同,它会直接认为这两个对象不相等,根本不会去比 equals。
后果:如果你只重写了 equals 没重写 hashCode,即使两个对象内容一样,它们也会被分到不同的桶里,导致你永远找不到存进去的对象。
第二步:精准定位(equals)
如果两个对象不幸分到了同一个桶里(哈希碰撞),HashMap 才会调用 equals() 挨个比较桶里的对象,确认到底是谁。
java
import java.util.Objects;
@Override
public int hashCode() {
// 只需要把你想要参与比较的字段丢进去即可
return Objects.hash(id, username, age);
}
11.String StringBuilder StringBuffer 区别
String 是不可变,一旦修改会创造个新的对象
StringBuilder和StringBuffer都可变
StringBuilder是线程不安全
StringBuffer是线程安全的用synchronized关键字实现