1.Lombok 是什么?常用注解有哪些?怎么用?注意点?如果要自己写 set 逻辑怎么办?
- Lombok 是第三方库,通过注解自动生成构造器getter/settertoString() 等,优化 JavaBean。
- 常用注解@Data@NoArgsConstructor@AllArgsConstructor。
- 使用步骤:
1)类上加注解(如 @Data),首次无提示可 Alt+Enter 导入 Lombok 依赖;
2)确保 IDEA 装了 Lombok 插件(2021+ 多数已内置);
3)开启注解处理Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processing -> Enable annotation processing。
- 查看生成成员Alt+7。
- 注意@AllArgsConstructor 在“无成员变量”时会变成无参构造。
- 自定义 set:可手写对应 setXxx(),Lombok 会让位,优先使用手写逻辑。

2.什么是设计模式?单例模式作用、好处、实现方案、核心理解?
- 设计模式:某类问题的成熟/优选解决方案。
- 单例作用:保证某个类全局只有一个对象。
- 好处:节省内存、统一访问点。
- 方案:
- 饿汉式:类加载即创建对象。
- 懒汉式:首次使用时再创建。
- 核心三步:
1)私有化构造器(阻止外部 new);
2)内部保存唯一实例;
3)提供唯一访问入口(通常静态方法)。
3.什么是饿汉式单例?如何实现?
类加载时就创建单例。
实现三步:私有构造器 -> 静态变量持有实例 -> 静态方法返回实例。
public class A {
//第一步:把类的构造器私有。
private A(){}
// 第二步:定义一个静态变量记住类的一个对象。
private static A a = new A();
//第三步:定义一个静态方法,返回对象。
public static A getInstance(){
return a;
}
}public class Demo011 {
public static void main(String[] args) {
//单例模式对象是无法自己new的
// A a0 = new A(); //报错,没有可以调用的构造器
//获取A对象
A a1 = A.getInstance();
A a2 = A.getInstance();
System.out.println(a1);
System.out.println(a2);
//结论:获取的单例对象内存地址一样,只有1个对象
}
}4.什么是懒汉式单例?如何实现?
(1)类加载时不创建对象,需要时通过调用方法再创建。
(2)
第一步:把类的构造器私有。
第二步:定义一个静态变量用于存储对象。
第三步:提供一个静态方法,在方法中判断并创建对象返回。
说明:该基础写法有线程安全问题,后续需用并发方案优化。
public class B {
/*
* 懒汉式单例模式开发步骤:
* 第一步:把类的构造器私有。
第二步:定义一个静态变量记住类的一个对象,不能初始化
第三步:提供一个静态方法,在方法中判断并创建对象返回
* */
//第一步:把类的构造器私有。
private B(){}
// 第二步:定义一个静态变量记住类的一个对象,不能初始化
private static B b;
//第三步:提供一个静态方法,在方法中判断并创建对象返回
//这个懒汉式不是最终代码,因为存在线程安全问题,等以后学习完多线程再优化
public static B getInstance(){
if(b==null){
b = new B();
}
return b;
}
}public class Demo011 {
public static void main(String[] args) {
//单例模式对象是无法自己new的
// A a0 = new A(); //报错,没有可以调用的构造器
//获取A对象
A a1 = A.getInstance();
A a2 = A.getInstance();
System.out.println(a1);
System.out.println(a2);
//结论:获取的单例对象内存地址一样,只有1个对象
//获取B对象
B b1 = B.getInstance();
B b2 = B.getInstance();
System.out.println(b1);
System.out.println(b2);
}
}5.什么是枚举?定义语法是什么?使用场景?
(1)枚举是一种特殊类。
(2)
修饰符 enum 枚举类名{
名称1 , 名称2, ... ;
其他成员…
}- 场景:表示有限且固定的一组取值(性别、状态、类型等),用于限制输入、提高可读性。
6.定义枚举有哪些注意点?
1)第一行只能写枚举常量,每个常量对应一个枚举对象。
2)从第二行起可写成员变量、方法、构造器。
3)枚举是最终类,不能被继承,父类是 java.lang.Enum。
4)枚举构造器只能是私有。
5)常用静态方法values()valueOf(String)。
package com.itheima._02枚举;
/**
* 枚举类: 一种特殊类。
* 作用:用于输入限制一组有效的数据,可读性更好
*/
public enum Gender {
//第一行(用的多)
MAN,//原理 public static final Gender MAN = new Gender()
WOMAN("女");//原理 public static final Gender WOMAN = new Gender("女")
//第二行开始(用的少)
//成员变量
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
//构造器
// public Gender(){} 报错
private Gender(){}
Gender(String value){//修饰符没有写也是private
this.value = value;
}
//定义枚举注意事项
// 1.枚举类的第一句只能罗列一些名称,这些名称都是常量,并且每个常量会记住枚举类的一个对象。
// 2.枚举类中,从第二句(行)开始,可以定义类的其他各种成员(成员变量、成员方法、构造器)。
// 3.枚举都是最终类,不可以被继承,枚举类都是继承java.lang.Enum类的。
// 4.举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
// 5.编译器为枚举类新增了几个静态方法,用于获取所有枚举对象或者某个枚举对象。
// public static 枚举类[] values(); 返回所有枚举对象
// public static 枚举类 valueOf(java.lang.String); 返回单个枚举对象
}package com.itheima._02枚举;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description Student
* @Author songyu
* @Date 2026-02-06 11:08
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private String name;
private int age;
// private String gender;//性别用字符串好不好?答:不好,输入任何值都可以,可能输入无效的数据
private Gender gender;//使用枚举进行限制性别的输入,可读性(用的少)
}package com.itheima._02枚举;
import java.util.Arrays;
/**
* @Description Demo021
* @Author songyu
* @Date 2026-02-06 11:06
*/
public class Demo021 {
public static void main(String[] args) {
//创建对象
Student s1 = new Student("播仔", 20, Gender.MAN);
Student s2 = new Student("播妞", 19, Gender.WOMAN);
//打印学生信息
System.out.println("姓名:"+s1.getName()+",性别:"+s1.getGender().getValue());//null
System.out.println("姓名:"+s2.getName()+",性别:"+s2.getGender().getValue());//女
//解决上面的问题
System.out.println("姓名:"+s1.getName()+",性别:"+(s1.getGender()==Gender.MAN?"男":"女"));//null
System.out.println("姓名:"+s2.getName()+",性别:"+s2.getGender().getValue());//女
//调用静态方法(用的少,了解即可)
Gender[] values = Gender.values();//所有枚举对象
System.out.println(Arrays.toString(values));//MAN,WOMAN
Gender man = Gender.valueOf("MAN");
System.out.println(man);//MAN
}
}7.为什么要使用抽象类?
当父类方法无法给出通用实现,但要求子类必须实现时,用抽象方法 + 抽象类强制规范子类行为。
8.什么是抽象类和抽象方法?
被 abstract 修饰的类是抽象类;被 abstract 修饰的方法是抽象方法。
9.抽象类使用注意事项有哪些?
1)抽象类不能实例化。
2)子类继承后要么重写全部抽象方法,要么自己也声明为抽象类。
3)抽象类可有普通成员变量/方法/构造器。
4)抽象类不一定有抽象方法;有抽象方法的类一定是抽象类。
10.定义接口的关键字是什么?
interface。示例public interface 接口名 {}
11.接口中的变量、方法有什么特点?
- 变量默认public static final(常量)。
- 方法默认public abstract(抽象方法,JDK8 前主流形态)。
12.类实现接口用什么关键字?实现后要做什么?
用 implements;实现类需重写接口中的抽象方法。
13.Java 中接口的作用是什么?
定义行为规范,约束不同类具备相同能力(方法契约)
14.接口注意事项有哪些?
1)接口不能创建对象。
2)接口变量是常量public static final)。
3)接口方法默认抽象public abstract)。
15.JDK8 开始接口新增了哪些方法?
- 默认方法default,由实现类对象调用。
- 静态方法static,必须接口名调用。
- 私有方法private(JDK9 才支持),仅接口内部可用。
说明:抽象/默认/静态方法默认可 public。
16.JDK8 为何给接口新增这些方法?
增强接口扩展能力,降低升级改造成本,提升可维护性。
17.接口和抽象类的区别?
- 类只能继承一个抽象类;类可实现多个接口。
- 继承与实现可并存。
- 接口可多继承接口。
- 抽象类偏“同类事物共性抽取”;接口偏“跨类型行为规范”。
18.Java中只能单继承,对不对?
不完全对。类是单继承;接口支持多继承。
19.什么是成员内部类?如何创建对象?
创建语法外部类.内部类 变量 = new 外部类(...).new 内部类(...);
20.成员内部类方法访问成员有什么特点?
遵循就近原则(局部 -> 内部类成员 -> 外部类成员);
可用 外部类名.this 获取当前外部类对象。
21.静态内部类访问外部类成员有什么特点?
可直接访问外部类静态成员;不能直接访问外部类实例成员。
22.什么是静态内部类?如何创建?访问外部类成员特点?
- 定义:被 static 修饰的成员内部类。
- 创建外部类.内部类 变量 = new 外部类.内部类(...);
- 访问特点:同 Q21(仅直接访问外部类静态成员)。
23.什么是局部内部类?
定义在方法中的内部类,通常不能加访问修饰符,仅在该方法内有效,作用域很小。
24.匿名内部类本质是什么?
本质是“某个父类的匿名子类对象”或“某个接口的匿名实现类对象”。
25.匿名内部类应用场景是什么?
当方法参数是抽象类/接口类型时,可直接传匿名内部类对象以简化代码。调用方法时,形参若是抽象类或接口,直接用匿名内部类作为实参传递。
26.匿名内部类做排序的核心规则是什么?
使用 Arrays.sort(T[] , Comparator<T>) 传入匿名比较器重写 compare:
- o1 - o2:升序
- o2 - o1:降序
返回规则:正数/负数/0 分别表示大于/小于/等于。

public static void main(String[] args) {
/*
Arrays类中提供了一个sort方法对数组中的元素进行排序,默认是按照升序排序,如果需要自定义排序规则,则需要使用重载的方法: Arrays.sort(T[] t, Comparator<T> c)。
参数1表示要排序的数组,参数二Comparator是一个接口,我们可以传递这个接口的匿名内部类对象,重写方法定
义排序规则。
关于比较规则:前面跟后面比,升序;后面跟前面比,降序。
如果大于,返回任意正整数。
如果小于,返回任意负整数。
如果等于,返回0即可。
*
* */
Integer[] arr = {10, 88, 52, 21, 76, 92, 28, 55, 39, 82};
System.out.println("排序前:"+Arrays.toString(arr));
//升序排序
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
//arr里面的元素已经被升序移动元素位置了
System.out.println("升序后:"+Arrays.toString(arr));
//降序
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println("降序后:"+Arrays.toString(arr));
}27.类与类、类与接口、接口与接口的关系?
1)类与类:单继承
2)类与接口:多实现
3)接口与接口:多继承