Loading...

文章背景图

Day 07-知识点汇总

2026-02-06
3
-
- 分钟

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 会让位,优先使用手写逻辑。

5-42.png

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 分别表示大于/小于/等于。

42-02.png
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)接口与接口:多继承

评论交流

文章目录