N

Norlcayn的博客

A text-focused Halo theme

  • 首页
  • 文章
  • 默认分类
  • 关于
主页 Java高级
文章

Java高级

发表于 2026-01-15 更新于 昨天
作者 Administrator
60~77 分钟 阅读

枚举

枚举是Java中一种特殊类型,一般用来做信息的标记和分类

在不是枚举的情况下,也可以实现信息的标记和分类:

package _enum;

public class EnumDemo01 {
    public static void main(String[] args) {
        useSeason(Season.AUTUMN);
    }

    public static void useSeason(String string) {
        switch (string) {
            case Season.SPRING -> System.out.println("春天");
            case Season.SUMMER -> System.out.println("夏天");
            case Season.AUTUMN -> System.out.println("秋天");
            case Season.WINTER -> System.out.println("冬天");
        }
    }
}

class Season {
    public static final String SPRING = "SPRING";
    public static final String SUMMER = "SUMMER";
    public static final String AUTUMN = "AUTUMN";
    public static final String WINTER = "WINTER";

    // 私有构造函数,防止实例化
    private Season() {}

    public static String[] getAllSeasons() {
        return new String[]{SPRING, SUMMER, AUTUMN, WINTER};
    }
}

使用枚举技术优化代码:

package _enum;

public class EnumDemo01 {
    public static void main(String[] args) {
        useSeason(Season.AUTUMN);
    }

    public static void useSeason(Season season) {
        switch (season) {
            case SPRING -> System.out.println("春天");
            case SUMMER -> System.out.println("夏天");
            case AUTUMN -> System.out.println("秋天");
            case WINTER -> System.out.println("冬天");
        }
    }

}

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER;
}

枚举入参严谨,提示性更好,代码优雅

枚举定义格式:

修饰符 enum 枚举类名 {
枚举项1, 枚举项2, 枚举项3...
}

枚举的特点

  1. 每一个枚举项其实就是该枚举类的一个对象
  2. 通过枚举类名去访问指定的枚举项
  3. 所有枚举类都是Enum的子类
  4. 枚举也是类,可以定义成员变量
  5. 枚举类的第一行上必须是枚举项,最后一个枚举项的分号是可以省略的。但如果枚举类有其他东西,就不能省略(推荐不省略)
  6. 枚举类可以有构造器,但必须是private的,它默认也是private
  7. 枚举类也可以有抽象方法,但枚举项必须重写该方法

类加载器

主要作用就是将类的字节码载入方法区中

加载时机:用到就加载。比如创建对象、调用类的静态成员、初始化继承体系、使用反射加载类的字节码

加载过程:加载、链接、初始化

第一步加载:

  • 通过包名 + 类名,获取这个类,准备用流进行传输
  • 将类加载到内存中
  • 加载完毕创建一个class对象

第二步链接:

  • 验证:验证类是否符合JVM规范,安全性检查
  • 准备:为static变量分配空间,设置默认值
  • 解析:将常量池中的符号引用解析为直接引用

``` package classloader;

public class ClassLoaderDemo01 { public static void main(String[] args) { ClassLoader classLoader = B.class.getClassLoader(); // 代码执行到这,表示: // 1. B类的字节码被加载到方法区,并完成链接(验证、准备、解析) // 2. C类的字节码也会被加载到方法区 // 3. 此时B和C都只是类结构,没有创建任何实例对象 // 4. B类中对C的引用是符号引用,尚未解析为直接引用

      B b = new B();

// 当创建B对象时: // 1. 在堆中为B实例分配内存 // 2. 执行B的实例初始化 // 3. 在初始化过程中,执行 C c = new C(),创建C的实例 // 4. 此时C的实例才在堆中分配内存,有了实际的地址值 } }

class B { C c = new C(); }

class C {

} ```

第三步初始化:

  • 初始化:根据程序员程序编码制定的主观计划去初始化类变量和其他资源
  • 可以理解为将类中的静态成员变量赋上真实的值

类加载器的分类

  • Bootstrap class loader:启动类加载器,虚拟机内置类加载器,通常表示为null。因为这个加载器是利用C++实现,所以获取到的只能是null
  • Platfrom class loader:平台类加载器,负责加载JDK中一些特殊的模块。负责加载lib/modules内部的类
  • 平台类加载器是从JDK9版本之后出现的
  • JDK9版本之前是Extension Class Loader,扩展类加载器。负责加载jre/lib/ext目录下的类
  • Application class loader:应用程序类加载器。负责加载自己写的类
  • 自定义类加载器:上级为Application,目前不做讲解
方法 功能
public Classloader getClassLoader() 获取该类的 类加载器对象

示例:

package classloader;

public class ClassLoaderDemo {
    public static void main(String[] args) {
        // Boostrap类加载器
        ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1);   // null

        // Application类加载器
        ClassLoader classLoader2 = ClassLoaderDemo.class.getClassLoader();
        System.out.println(classLoader2);   // jdk.internal.loader.ClassLoaders$AppClassLoader@36baf30c

        // 获取上下级关系
        System.out.println(classLoader2.getParent());   // jdk.internal.loader.ClassLoaders$PlatformClassLoader@b4c966a
        System.out.println(classLoader2.getParent().getParent());// jdk.internal.loader.ClassLoaders$PlatformClassLoader@b4c966a

    }
}

Application类加载器的上级:Platform类加载器

Platform类加载器的上级:Bootstrap类加载器

双亲委派模式

  1. 如果一个类加载器收到了类加载请求,它并不会自己先去加载
  2. 而是把这个请求委托给父类的加载器去执行
  3. 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归
  4. 请求最终将到达顶层的启动类加载器
  5. 如果父类加载器可以完成类加载任务,就成功返回
  6. 但父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式
  7. 这种加载模式的好处在于避免类的重复加载

Snipaste_2025-08-01_20-07-00

反射

  • 框架技术的灵魂
  • 在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意属性和方法
  • 这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制

获取类的字节码对象

  1. Class.forName(“全类名”);
  2. 类名.class
  3. 对象.getClass();

示例:

package reflect;

import pojo.Student;

public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1. Class.forName("全类名");
        Class<?> class1 = Class.forName("pojo.Student");

        // 2. 类名.class
        Class<Student> class2 = Student.class;

        // 3. 对象.getClass();
        Student s = new Student();
        Class<? extends Student> class3 = s.getClass();

        System.out.println(class1);     // class pojo.Student
        System.out.println(class2);     // class pojo.Student
        System.out.println(class3);     // class pojo.Student
        System.out.println((class1 == class2) && (class2 == class3));   // 结果为true,因为字节码文件唯一
    }
}

反射类中的构造方法

方法 功能
Constructor<?>[] getConstructors() 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors() 返回所有构造方法对象的数组
Constructor getConstructor(Class<?>… parameterTypes) 返回单个公共构造方法对象
Constructor getDeclaredConstructor(Class<?>… parameterTypes) 返回单个构造方法对象

示例:

package reflect;

import java.lang.reflect.Constructor;
import java.util.Arrays;

public class ReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        // 获取类的字节码对象
        Class<?> class1 = Class.forName("pojo.Student");

        // 反射构造方法对象,批量反射
        Constructor<?>[] constructors1 = class1.getConstructors();
        Constructor<?>[] constructors2 = class1.getDeclaredConstructors();

        System.out.println(Arrays.toString(constructors1));
        // [public pojo.Student(), public pojo.Student(java.lang.String,int)]
        System.out.println(Arrays.toString(constructors2));
        // [public pojo.Student(), private pojo.Student(int), private pojo.Student(java.lang.String), public pojo.Student(java.lang.String,int)]

        // 反射构造方法对象,单独反射
        Constructor<?> constructor1 = class1.getConstructor(String.class, int.class);   // 对应构造方法的参数,提供参数的字节码对象
        System.out.println(constructor1);   // public pojo.Student(java.lang.String,int)

        Constructor<?> constructor2 = class1.getDeclaredConstructor(String.class);
        System.out.println(constructor2);   // private pojo.Student(java.lang.String)
    }
}

通过构造方法对象进行实例化:

package reflect;

import pojo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo03 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> class1 = Student.class;
        Constructor<Student> constructor1 = class1.getConstructor(String.class, int.class);// 这是公共的构造方法

        // ---------------------------------------------------------------------------- //
        Student student1 = constructor1.newInstance("张三", 18);      
        System.out.println(student1);       // Student{name='张三', age=18}

        // ---------------------------------------------------------------------------- //
        Constructor<Student> constructor2 = class1.getDeclaredConstructor(String.class);     // 这是私有的构造方法

        // Student student2 = constructor2.newInstance("张三");      // 报错:IllegalAccessException
        // System.out.println(student2);

        constructor2.setAccessible(true);   // 取消权限检查
        Student student2 = constructor2.newInstance("张三");
        System.out.println(student2);       // Student{name='张三', age=0}

    }
}

newInstance:实例化对象的方法

setAccessible:设置为true表示取消权限检查

反射类中的成员变量

方法 功能
Field[] getFields() 返回所有公共成员变量对象的数据
Field[] getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象

示例:

package reflect;

import pojo.Student;

import java.lang.reflect.Field;
import java.util.Arrays;

public class ReflectDemo04 {
    public static void main(String[] args) throws NoSuchFieldException {
        Class<Student> class1 = Student.class;

        Field[] fields1 = class1.getFields();
        System.out.println(Arrays.toString(fields1));   // [public int pojo.Student.id]

        Field[] fields2 = class1.getDeclaredFields();
        System.out.println(Arrays.toString(fields2));   // [public int pojo.Student.id, private java.lang.String pojo.Student.name, private int pojo.Student.age]

        Field name = class1.getField("id");
        Field age = class1.getDeclaredField("age");
        System.out.println(name);                       // public int pojo.Student.id
        System.out.println(age);                        // private int pojo.Student.age
    }
}

Field类的设置和获取方法:

方法 说明
void set(Object obj,Object value) 赋值
Object get(Object obj) 获取值

示例:

package reflect;

import pojo.Student;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo05 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Class<Student> studentClass = Student.class;

        // 利用反射创建对象
        Student student1 = studentClass.getConstructor().newInstance();
        Student student2 = studentClass.getConstructor().newInstance();

        // 获取成员变量对象
        Field name = studentClass.getDeclaredField("name");
        Field age = studentClass.getDeclaredField("age");

        // 取消权限检查
        name.setAccessible(true);
        age.setAccessible(true);

        // 赋值操作
        name.set(student1,"张三");
        age.set(student1,18);

        name.set(student2,"李四");
        age.set(student2,20);

        // 打印对象信息
        System.out.println(student1);   // Student{name='张三', age=18}
        System.out.println(student2);   // Student{name='李四', age=20}

        // 获取成员变量的值
        String s1 = (String) name.get(student1);
        String s2 = (String) name.get(student2);
        System.out.println(s1);     // 张三
        System.out.println(s2);     // 李四
    }
}

反射建议:禁止暴力反射操作

反射类中的成员方法

方法 功能
Method[] getMethods() 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>… parameterTypes) 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>… parameterTypes) 返回单个成员方法对象
  • Method类用于执行方法的方法
方法 功能
Object invoke(Object obj, Object… args) 运行方法

示例:

package reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectDemo06 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Zi> class1 = Zi.class;

        // 获取成员方法列表
        Method[] methods1 = class1.getMethods();
        System.out.println(Arrays.toString(methods1));  // 很长的一条数组,因为继承了Fu和Object,所以会获取到它们的所有方法

        Method[] methods2 = class1.getDeclaredMethods();
        System.out.println(Arrays.toString(methods2));  // [public void reflect.Zi.count(int[]), private void reflect.Zi.printHello(double), private void reflect.Zi.printHello(int)]

        // 获取指定成员方法
        Method count = class1.getMethod("count", int[].class);// 第二个以及以后的参数用于区分重载方法
        Zi zi = class1.getConstructor().newInstance();  // 创建调用方法的对象

        count.invoke(zi,new int[]{1,2,3,4,5});  // 调用方法
    }
}

class Fu {
    public void show() {
        System.out.println("Fu Show ...");
    }
}

class Zi extends Fu{
    public Zi() {};

    public void count(int... nums) {
        int cnt = 0;
        for (int i = 0; i < nums.length; i++) {
            cnt += nums[i];
        }
        System.out.println(cnt);
    }

    private void printHello(int i) {
        System.out.println("Hello");
    }

    private void printHello(double i) {
        System.out.println("Hello");
    }
}

反射练习

伪泛型

需求:请向一个Integer的集合,添加一个String字符串

思路:Java中的泛型是假的,只在编译的时候有效

示例:

package reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;

public class ReflectTest01 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5);

        Class<? extends ArrayList> class1 = list.getClass();
        Method add = class1.getMethod("add", Object.class);
        add.invoke(list,"你好");

        System.out.println(list);   // [1, 2, 3, 4, 5, 你好]
    }
}

综合练习

需求:

编写三个任意的Javabean类:Student、Teacher、Worker

属性均为name、age

方法要求:

  1. Student里面写学习study和吃饭eat的方法(方法无参返回)
  2. Teacher里面写上课teach和吃饭eat的方法(方法无参返回)
  3. Worker里面写工作work和睡觉sleep的方法

本地新建配置文件properties

属性:className=Student类的全类名,methodName=study

在测试类中读取properties文件中的两个属性值

利用反射创建学生类的对象,并调用方法

修改配置文件,不修改代码,运行老师类中的上课方法

修改配置文件,不修改代码,运行工人类中的工作方法

示例:

package reflect;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;

public class Test {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();

        try (FileInputStream fis = new FileInputStream("Day06\\config.properties")) {
            prop.load(fis);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 获取字节码对象
        Class<?> class1 = Class.forName(prop.getProperty("className"));
        // 创建对象
        Object o = class1.
                getConstructor(String.class,int.class).
                newInstance(prop.getProperty("name"),Integer.parseInt(prop.getProperty("age")));
        // 获取成员方法对象
        Method method = class1.getMethod(prop.getProperty("methodName"));
// 调用方法
        method.invoke(o);
    }
}

config.properties:

className=reflect.Worker
methodName=work
name=Alice
age=28

注解

  • Annotation表示注解,是JDK1.5的新特性。主要作用:对程序进行标注
  • 理解:注释是给人看的,注解是给JVM虚拟机看的。通过注解可以给类增加额外的信息。编译器或JVM可以根据注解来完成对应的功能。

JDK中常见的注解:

  • @Override:表示方法的重写
  • @Deprecated:表示修饰的方法已经过时
  • @SuppressWarning(“all”):压制警告

注解常用位置:

  1. 类
  2. 方法

自定义注解

  • 自定义注解单独存在意义不大,一般会跟反射结合起来使用
// 格式
public @interface 注解名称 {
public 属性类型 属性名() default 默认值;
}

// 示例
public @interface Anno {
String show() default "show...";
}

属性类型:

  • 基本数据类型
  • String
  • Class
  • 注解
  • 枚举
  • 以上类型的一维数组

Snipaste_2025-08-01_23-00-39

当属性不存在默认值时,使用注解需要指定属性值:

package anno;

@MyAnno02(show = "Hello")
public class MyAnnoDemo01 {
    @MyAnno02(show = "World",test = "CBA")
    public static void main(String[] args) {
        method();
    }

    @MyAnno03("Test")   // 如果属性名为value,可以省略
    public static void method() {
        System.out.println("method");
    }
}

@interface MyAnno02 {
    String show();
    String test() default "ABC";
}

@interface MyAnno03 {
    String value();
}
  • 在使用注解时,如果注解的属性没有给出默认值,需要手动给出
  • @Anno(name=”张三”)
  • 如果数组中只有一个属性值,在使用时{}是可以省略的
  • 如果只有一个属性名字为value没有赋值,使用时直接给出值,不需要写属性名

自定义测试注解

需求:自定义一个@Test,用于指定类的方法上。如果类中的某个的方法上使用了该注解,就执行该方法

示例:

package anno;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyTestDemo01 {
    public static void main(String[] args) throws Exception {
        Class<MethodDemo> clazz = MethodDemo.class;

        MethodDemo methodDemo = clazz.getConstructor().newInstance();

        // 获取该类中所有成员方法对象
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            // 判断该方法是否存在注解
            if (method.isAnnotationPresent(Test.class)) {
                method.invoke(methodDemo);
            }
        }
    }
}

@interface Test {}

class MethodDemo {
    public MethodDemo() {};
    @Test
    public void show() {
        System.out.println("show");
    }

    @Test
    public void print() {
        System.out.println("print");
    }

    public void method() {
        System.out.println("method");
    }
}

测试类代码没有问题,但是执行后没有调用show和print方法

主要是因为注解存在生命周期:源代码阶段、字节码阶段、运行阶段,默认是处于字节码阶段

但是反射是在运行阶段的进行操作,所以无法正确识别到注解

isAnnotationPresent():查看是否存在对应注解,参数为注解的字节码对象

元注解

  • 元注解就是用在注解上的注解
元注解名 说明
@Target 指定了注解能在哪里使用
@Retention 可以理解为保留时间(生命周期)

@Target:用来标识注解使用的位置,如果没有使用该注解表示,则自定义的注解可以使用在任意位置

Snipaste_2025-08-01_23-27-36

@Retention:用来标识注解的生命周期(有效范围)

Snipaste_2025-08-01_23-31-06

将自定义测试注解案例进行修改:

package anno;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyTestDemo01 {
    public static void main(String[] args) throws Exception {
        Class<MethodDemo> clazz = MethodDemo.class;

        MethodDemo methodDemo = clazz.getConstructor().newInstance();

        // 获取该类中所有成员方法对象
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            // 判断该方法是否存在注解
            if (method.isAnnotationPresent(Test.class)) {
                method.invoke(methodDemo);
            }
        }
    }
}

@Retention(RetentionPolicy.RUNTIME)
@interface Test {}

class MethodDemo {
    public MethodDemo() {};
    @Test
    public void show() {
        System.out.println("show");
    }

    @Test
    public void print() {
        System.out.println("print");
    }

    public void method() {
        System.out.println("method");
    }
}

现在就可以正确调用show和print方法了

动态代理

  • 动态代理是对象的另外一种创建方式,这种方式可以在不修改源码的情况下,增强方法
  • 动态代理就是在运行时生成代理类,无需手动为每个目标类编写代理类
  • java.lang.reflect.Proxy类:提供了使用动态代理方式创建对象的API
方法 说明
static Object newProxyInstance( ClassLoader loader, Class<?>[] interfaces, InvocationHandler h ) 参数一: 用于指定用哪个类加载器,去加载生成的实现类 参数二: 指定接口,这些接口用于指定生成的实现类中有什么 也就是有哪些方法 参数三: 用来指定生成的实现类中不同方法的实现方案

如果目标类的方法不是通过接口实现的,JDK动态代理(Proxy.newProxyInstance)无法直接使用

代理

类似于通过一个中间类对源方法进行增强

Snipaste_2025-08-01_23-43-05

SaleImpl这个类就是中间类(代理类)

不过每当有用户需要进行新的方法增强时,就得重新编写另一份专门的代理类

这种代理方式被称为静态代理

示例

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("all")
public class ProxyDemo01 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        // 参数一:应用程序加载器
        // 参数二:List字节码对象数组
        // 参数三:对具体方法的增强方案
        List<Integer> o = (List<Integer>) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{List.class}, new InvocationHandler() {
            // proxy:生成的代理对象,一般不直接在内部使用
            // method:所有代理的方法
            // args:调用方法的时候,传入的实际参数
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String name = method.getName();
                long begin = 0, end = 0;
                if ("add".equals(name)) {
                    begin = System.currentTimeMillis();
                    Object invoke = method.invoke(list, args);
                    end = System.currentTimeMillis();
                    System.out.println("耗时:" + (end - begin));
                    return invoke;
                }
                return null;
            }
        });

        o.add(111);
        o.add(222);
        o.add(333);

        System.out.println(list);
    }

    public static void showClassLoader() {
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);  // jdk.internal.loader.ClassLoaders$AppClassLoader@36baf30c
    }
}

实现动态代理的步骤较为复杂,不需要会熟练使用,但一定要认真理解

但在Spring框架中,有面向切面编程(AOP),其中已经对动态代理进行了封装

小结

  • 动态代理是对象的另外一种创建方式,这种方式可以在不修改源码的情况下,增强方法
  • 代理对象可以在原有功能的基础上进行增强
  • 动态代理在运行时动态的生成代理类,无需手动为每个目标类编写代理类
  • 使用Proxy中的newProxyInstance()方法创建代理对象
Java
Java语法 Java枚举 类加载器 反射 注解技术 动态代理
许可协议:  CC BY 4.0
分享

相关文章

1月 15, 2026

Java异常处理

异常的介绍和体系结构 异常介绍 指的是程序在编译或执行过程中,出现的非正常的情况(错误) ArrayIndexOutOfBoundsException:索引越界异常 ClassCaseException:类型转换异常 NullPointerException:空指针异常 注意:语法错误,不是异常 异

1月 15, 2026

Java网络编程

网络编程概念 可以让设备中的程序与网络上其他设备中的程序进行数据交互的技术(实现网络通信) 基本的通信架构分为两种:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端) 无论是CS架构还是BS架构,都必须依赖网络编程 Java中提供了java.ne

1月 15, 2026

Java面向对象编程

面向对象介绍 面向对象:并不是一个技术,而是一种编程的指导思想 以什么形式组织代码,以什么思路解决问题 为什么要学习面向对象? 因为生活中,我们要解决问题时,就是采用这种指导思想去解决的 所以,我们写程序去解决问题时,如果也能采用这种指导思想 就会使编程变得非常简单,程序也便于理解 面向对象,重点学

下一篇

Java基础

上一篇

Java常用API

最近更新

  • Hello Halo
  • 状态机
  • 数据表设计规范
  • 缓存优化
  • 事务失效

热门标签

Halo 异常处理 Redisson 并行 Vue 并发 递归 请求限流 SpringAMQP 类加载器

目录

©2026 Norlcayn的博客. 保留部分权利。

使用 Halo 主题 Chirpy