首页 > 编程语言 >Java 反射机制

Java 反射机制

时间:2024-09-10 19:23:46浏览次数:13  
标签:反射 Java name 获取 注解 机制 方法 public String

目录

一. 概述

二. 反射的特点

三. 反射主要应用

四. 反射注意事项

五. 代码示例详解

1. 解析图:

2. 获取字节码对象

3. 通过反射获取构造函数并创建对象

4. 通过反射获取对象字段信息

5. 通过反射获取方法并执行

6. 通过反射获取注解信息

六. 总结

1. 获取Class字节码对象方式

2. 利用反射获取构造函数对象

3. 利用反射获取对象字段信息

4. 利用反射获取方法并执行

5. 利用反射获取类、字段、方法、方法参数中的注解


一. 概述

        Java 反射机制是Java语言的一个特性,它允许程序在运行时访问、检查和修改它自己的结构,例如类、接口、字段(成员变量)和方法。反射机制使得Java程序能够在运行时动态地创建对象、调用方法、改变字段值等,而不需要在编译时就知道具体的类信息。

        说人话:就是通过Class字节码文件获取对象信息、成员变量、构造、方法,还可以获取到父类中方法,私有方法等。

二. 反射的特点

  1. 动态性: 反射允许程序在运行时加载、探查、使用编译期间完全未知的.class文件。

  2. 通用性: 反射提供了一种通用的方法来处理对象,不依赖于具体的类。

  3. 扩展性: 反射允许程序动态地扩展,可以处理在编译时未知的类。

  4. 内省: 反射提供了一种方式来获取类和对象的信息,如字段、方法、构造器等。

三. 反射主要应用

  1. 创建灵活的代码: 可以使用反射动态地创建对象和调用方法,使代码更加灵活。

  2. 开发框架: 许多Java框架(如Spring、Hibernate)使用反射来实现依赖注入、代理模式等功能。

  3. 测试工具: JUnit 等测试框架使用反射来动态地调用测试方法。

  4. 动态代理: Java 提供了java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现动态代理。

  5. 访问私有成员: 通过反射可以访问和修改私有字段和方法。

四. 反射注意事项

  1. 性能开销: 反射操作通常比直接的Java代码操作要慢,因为它们需要额外的解析步骤。

  2. 安全限制: 反射可能破坏封装性,因此需要确保代码的安全性。

  3. 异常处理: 反射操作可能会抛出多种异常,如ClassNotFoundExceptionNoSuchMethodExceptionIllegalAccessException等(也可通过反射机制获取方法抛出的异常信息)。

五. 代码示例详解

1. 解析图:

通过Class字节码对象可以获取:

  1. 获取构造方法对象
    1. 获取构造权限修饰符(public,protected,private)
    2. 获取构造函数名称
    3. 获取形参
    4. 创建对象 newInstance()
  2. 获取字段(成员变量)
    1. 获取字段权限修饰符(public,protected,private)
    2. 获取字段名称
    3. 获取参数类型
    4. 设置值/获取值
  3. 获取成员方法
    1. 获取方法修饰符(public,protected,private)
    2. 获取方法名称
    3. 获取形参
    4. 运行方法

2. 获取字节码对象

        通过反射机制获取对象信息需要先获取 Class 字节码对象,获取Class字节码对象可以通过三种方式获取:

  1. 通过全限定名:Class 类中的静态方法 forName(全类名)
  2. 通过类.class:类名称.class
  3. 通过对象中的方法:对象中getClass()方法获取字节码对象
package com.demo.reflect;
/**
 * 文件名:Mamin
 * 创建者:
 * 创建时间:2024-09-09
 * 描述:获取class字节码对象三种方式
 */
public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        //1. 通过权限定名获取字节码文件(常用方式)
        Class forClass =  Class.forName("com.demo.reflect.User");
        //2. 通过类名获取class字节码对象(多使用在参数中)
        Class userClass = User.class;
        //3. 通过对象获取class字节码对象(通过对象获取字节码对象时使用)
        User user = new User();
        Class obectUserClass = user.getClass();
        //因为class字节码文件在硬盘中是唯一的,所以说三种方法获得的class对象是同一个
        if((forClass == userClass) && (forClass == obectUserClass)){
            System.out.println("同一个对象");
        }
    }
}

3. 通过反射获取构造函数并创建对象

3.1. Class类中用于获取构造方法的方法

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

3.2. Constructor类中用于创建对象的方法

//根据指定的构造方法创建对象
Constructor类中用于创建对象的方法 T newInstance(Object...initargs);
//设置为true,表示取消访问检查(私有修饰符必须设置这个)
setAccessible(boolean flag);

3.3. 代码

  1. 创建User用户类
    package com.demo.reflect;
    
    /**
     * 文件名:User
     * 创建者:
     * 创建时间:2024-09-09
     * 描述:自定义用户信息类
     */
    public class User {
        private String name; //名称
        private int age; //年龄
        public boolean sex; // 性别
    
        public User() {
        }
    
        public User(String name) {
            this.name = name;
        }
    
        protected User(int age) {
            this.age = age;
        }
    
        private User(boolean sex) {
            this.sex = sex;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public boolean isSex() {
            return sex;
        }
    
        public void setSex(boolean sex) {
            this.sex = sex;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", sex=" + sex +
                    '}';
        }
    }
    
  2. 创建测试类
    package com.demo.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Parameter;
    
    /**
     * 文件名:Demo01
     * 创建者:
     * 创建时间:2024-09-09
     * 描述:
     */
    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //1.通过权限定名获取class字节码对象
            Class clazz =  Class.forName("com.demo.reflect.User");
            //2.获取单个 private 修饰的有参构造
            Constructor privateCon = clazz.getDeclaredConstructor(String.class);
            privateCon.setAccessible(true); //如果修饰符为私有的必须设置为true,表示取消访问检查
            System.out.println("获取单个 private 私有构造:"+privateCon);
    
            //3.通过 newInstance() 方法创建User对象,参数是构造里的参数
            User user = (User) privateCon.newInstance("码农");
            System.out.println(user);
    
            //4.获取修饰符 private 返回的是int类型,这个jdk定义的常量,可在jdk文档中查看
            int pri = privateCon.getModifiers();
            System.out.println(pri);
    
            //5.获取构造参数
            Parameter[] pars = privateCon.getParameters();
            for (Parameter par : pars) {
                System.out.println(par);
            }
    
            System.out.println("===================下面都是获取构造对象,其他都一样=============================");
    
            Constructor[] pubCon = clazz.getConstructors();
            for(Constructor con : pubCon){
                System.out.println("获取所有public修饰的构造方法 : "+con);
            }
    
            //获取 public,private,protected 修饰的所有构造
            Constructor[] cons = clazz.getDeclaredConstructors();
            for(Constructor c : cons){
                System.out.println("获取所有构造包括 private 和 protected : "+c);
            }
    
            //获取单个 private 修饰的有参构造
            Constructor privCon = clazz.getDeclaredConstructor(boolean.class);
            System.out.println("获取单个 private 私有构造:"+privCon);
        }
    }
    
  3. 测试结果

4. 通过反射获取对象字段信息

4.1. Class类中获取字段属性信息的方法

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

4.2. Field类中创建对象的方法

//赋值
void set(Object obj,Object value);
//获取值
Object get(Object obj);

4.3. 代码

  1. 测试类
    package com.demo.reflect;
    
    
    import java.lang.reflect.Field;
    
    /**
     * 文件名:Demo02
     * 创建者:
     * 创建时间:2024-09-09
     * 描述:通过反射获取成员变量测试类
     */
    public class Demo02 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
            //1.通过权限定名获取class字节码对象
            Class clazz =  Class.forName("com.demo.reflect.User");
            //2.获取公开的所有属性
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                System.out.println("获取public修饰的属性:"+field);
            }
            //3.获取所有的的属性,包括私有的属性
            Field[] fields1 = clazz.getDeclaredFields();
            for (Field field : fields1) {
                System.out.println("获取public、private、protected修饰的属性:"+field);
            }
            //4.获取单个属性私有修饰也可获取
            Field name =  clazz.getDeclaredField("name");
            name.setAccessible(true); //如果修饰符为私有的必须设置为true,表示取消访问检查
            System.out.println("获取单个属性:"+name);
            //5.获取属性名称
            String cName = name.getName();
            System.out.println("获取属性名称:"+cName);
            //6.获取属性修饰符
            int pr = name.getModifiers();
            System.out.println("获取修饰符:"+pr);
            //7.获取成员变量的类型
            Class cType = name.getType();
            System.out.println("获取成员变量的类型:"+cType);
            //8.获取属性的值
            User user = new User();
            user.setName("测试");
            Object userName = name.get(user);
            System.out.println("获取对象的值:"+userName);
    
            //9.通过反射修改对象的值
            name.set(user,"张三"); // 如果字段修饰符是私有修饰符需要设置name.setAccessible(true),取消访问检查
            System.out.println("修改对象值:"+user);
        }
    }
    
  2. 测试结果

5. 通过反射获取方法并执行

5.1. 利用Class字节码对象通过反射获取成员方法对象

//返回所有公共成员方法对象的数组,包括继承的
Method[] getMethods();
//返回所有成员方法对象的数组,不包括继承的
Method[] getDeclaredMethods();
//返回单个公共成员方法对象
Method getMethod(String name, Class<?>.. parameterTypes);
//返回单个成员方法对象
Method getDeclaredMethod(String name, Class<?>..parameterTypes);

5.2. 创建方法对象并执行方法

//Method类中用于创建对象的方法
//参数一:用obj对象调用该方法
//参数二:调用方法的传递的参数(如果没有就不写)
//返回值:方法的返回值(如果没有就不写)
Object invoke(Object obj, Object... args);//运行方法

5.3. 代码

  1. 在User类中添加新成员方法
    package com.demo.reflect;
    
    import java.io.IOException;
    
    /**
     * 文件名:User
     * 创建者:
     * 创建时间:2024-09-09
     * 描述:自定义用户信息类
     */
    public class User {
        private String name; //名称
        private int age; //年龄
        public boolean sex; // 性别
        public User() {}
        public User(String name) {
            this.name = name;
        }
        protected User(int age) {
            this.age = age;
        }
        private User(boolean sex) {
            this.sex = sex;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public boolean isSex() {
            return sex;
        }
        public void setSex(boolean sex) {
            this.sex = sex;
        }
    
        private String eat(String name)throws IOException {
            return name+"在吃饭";
        }
        private void game(String name){
            System.out.println(name+"在打游戏");
        }
    
        public String work(String name){
            System.out.println(name+"在工作");
            return "小明工作很忙";
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", sex=" + sex +
                    '}';
        }
    }
    
  2. 测试类型
    package com.demo.reflect;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.lang.reflect.Parameter;
    
    /**
     * 文件名:Demo03
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:通过反射获取对象成员方法测试类
     */
    public class Demo03 {
    
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            //1.通过权限定名获取class字节码对象
            Class clazz =  Class.forName("com.demo.reflect.User");
    
            //2.获取对象方法信息(这个返回的方法会包含父类公开的方法)
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
    
            //3.获取当前对象的方法包括私有方法(这个不会返回父类的方法)
            Method[] methods1= clazz.getDeclaredMethods();
            for (Method method : methods1) {
                System.out.println(method);
            }
    
            //4.获取指定单个私有的方法
            Method method = clazz.getDeclaredMethod("eat", String.class);
            System.out.println("获取指定单个私有的方法:"+method);
            System.out.println("方法修饰符:"+method.getModifiers());//获取方法的修饰符
            System.out.println("方法名字:"+method.getName());//获取方法的名字
            System.out.println("参数个数:"+method.getParameterCount());//获取参数个数
            Parameter[] parameters = method.getParameters(); //获取方法的参数
            for (Parameter parameter : parameters) {
                System.out.println("方法参数:"+parameter);
            }
            Class[] ex = method.getExceptionTypes(); //获取方法的抛出的异常
            for (Class aClass : ex) {
                System.out.println("异常信息"+aClass);
            }
    
            //5.获取指定单个方法(包括私有)并运行某个方法
            Method met = clazz.getDeclaredMethod("game",String.class);
            met.setAccessible(true);如果修饰符为私有的必须设置为true,表示取消访问检查
            //运行方法
            //参数一:用obj对象调用该方法
            //参数二:调用方法的传递的参数(如果没有就不写)
            //返回值:方法的返回值(如果没有就不写)
            User user = new User();
            met.invoke(user,"小明");
    
            //6.获取公开的单个有参方法并运行,打印返回值
            Method method1 = clazz.getMethod("work", String.class);
            Object res = method1.invoke(user,"小明");
            System.out.println("返回值:"+res);
    
        }
    }
    
  3. 测试结果

6. 通过反射获取注解信息

6.1. 在java中可以通过反射的方式获取类、字段、方法、方法参数上的注解,java中的注解有广发的应用,特别是在框架开发上,基于注解的实现框架多不胜数。

注解获取主要从:

  1. 获取java类注解
  2. 获取对象属性上注解
  3. 获取方法上注解
  4. 获取方法参数注解

6.2. 代码实现

  1. 自定义注解(类注解、字段注解、方法注解、方法参数注解)
     
    package com.demo.reflect;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    /**
     * 文件名:MyAnnotation
     * 创建者:
     * 创建时间:2024-09-10
     * 描述: 自己定义一个类上使用的注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotationCalss {
        String value();
    }
    
    package com.demo.reflect;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    /**
     * 文件名:MyAnnotationField
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:自定义一个字段上使用的注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotationField {
        String value();
    }
    
    package com.demo.reflect;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    /**
     * 文件名:MyAnnotationMethod
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:  自定义一个方法上使用的注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotationMethod {
        String value();
    }
    
    package com.demo.reflect;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    /**
     * 文件名:MyAnnotationCalssParameter
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:自定义一个方法参数上使用的注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotationParameter {
        String value();
    }
    
  2. 定义普通 java 类
    package com.demo.reflect;
    
    /**
     * 文件名:MyClass
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:自定义类,在类上使用自己定义的 @MyAnnotation
     */
    @MyAnnotationCalss(value = "类注解")
    public class MyClass {
    
        @MyAnnotationField(value = "Field-name")
        private String name;
        @MyAnnotationField(value = "Field-age")
        private int age;
    
        @MyAnnotationMethod(value = "Method-game")
        private void game(String name){
            System.out.println(name+"在打游戏");
        }
    
        @MyAnnotationMethod(value = "Method-work")
        public String work(@MyAnnotationParameter(value = "Parameter-name") String name){
            System.out.println(name+"在工作");
            return "小明工作很忙";
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
  3. 定义测试类
    package com.demo.reflect;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * 文件名:AnnotationTest
     * 创建者:
     * 创建时间:2024-09-10
     * 描述:通过反射获取 类 属性 方法 方法中参数 的注解测试类
     */
    public class AnnotationTest {
        public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
            Class<MyClass> clazz = MyClass.class;
    
            //1.获取类上带有 @MyAnnotationCalss 注解的实例(这个获取的是多个注解)
            Annotation[] myAnnotations = clazz.getAnnotations();
            for (Annotation annotation : myAnnotations) {
                //多个注解需要判断注解类型
                if(annotation instanceof MyAnnotationCalss){
                    MyAnnotationCalss myAnnotat =((MyAnnotationCalss) annotation);
                    System.out.println("获取类上注解的值:"+myAnnotat.value());
                }
            }
    
            //2.获取类上带有 @MyAnnotationCalss 注解的实例(单个获取,需要传入注解class对象)
            MyAnnotationCalss myAnnotation = clazz.getAnnotation(MyAnnotationCalss.class);
            System.out.println("获取类上注解的值:"+myAnnotation.value());
    
            //3.获取方法上带有 @MyAnnotationMethod 注解的实例
            Method method = clazz.getDeclaredMethod("work",String.class);
            MyAnnotationMethod annotation = method.getAnnotation(MyAnnotationMethod.class);
            System.out.println("获取方法上注解的值:"+annotation.value());
    
            //4.获取方法参数带有 @MyAnnotationParameter 注解的实例(这个返回的是一个二维数组)
            Annotation[][] annotations = method.getParameterAnnotations();
            for (Annotation[] annotation1 : annotations) {
                for (Annotation annotation2 : annotation1) {
                    MyAnnotationParameter myAnnotationParameter = (MyAnnotationParameter) annotation2;
                    System.out.println("获取参数注解的值:"+myAnnotationParameter.value());
                }
            }
    
            //4.获取字段上带有 MyAnnotationField 注解的实例 (获取多个注解)
            Field field = clazz.getDeclaredField("name");
            Annotation[] annots = field.getAnnotations();
            for (Annotation annot : annots) {
                if(annot instanceof MyAnnotationField){
                    System.out.println("字段上的注解:"+annot);
                }
            }
    
            //5.获取字段上带有 MyAnnotationField 注解的实例(获取单个注解)
            MyAnnotationField myAnnotationField = field.getAnnotation(MyAnnotationField.class);
            System.out.println("获取属性注解的值:"+myAnnotationField.value());
    
        }
    }
    
  4. 测试结果

六. 总结

1. 获取Class字节码对象方式

//1. 通过权限定名获取字节码文件(常用方式)
Class forClass =  Class.forName("com.demo.reflect.User");
//2. 通过类名获取class字节码对象(多使用在参数中)
Class userClass = User.class;
//3. 通过对象获取class字节码对象(通过对象获取字节码对象时使用)
User user = new User();
Class obectUserClass = user.getClass();

2. 利用反射获取构造函数对象

//1.返回所有公共构造方法对象的数组
Constructor<?>[] getConstructors();
//2.返回所有构造方法对象的数组
Constructor<?>[] getDeclaredConstructors();
//3.返回单个公共构造方法对象
Constructor<T> getConstructor(Class<?>... parameterTypes);
//4.返回单个构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>.. parameterTypes)


//Constructor类中用于创建对象的方法
//根据指定的构造方法创建对象
T newInstance(Object...initargs);
//设置为true,表示取消访问检查(私有修饰符必须设置这个)
setAccessible(boolean flag);

3. 利用反射获取对象字段信息

//1.返回所有公共成员变量对象的数组
Field[] getFields();
//2.返回所有成员变量对象的数组
Field[] getDeclaredFields();
//3.返回单个公共成员变量对象
Field getField(String name);
//4.返回单个成员变量对象
Field getDeclaredField(String name);


//赋值
void set(Object obj,Object value);
//获取值
Object get(Object obj);


4. 利用反射获取方法并执行

//1.返回所有公共成员方法对象的数组,包括继承的
Method[] getMethods();
//2.返回所有成员方法对象的数组,不包括继承的
Method[] getDeclaredMethods();
//3.返回单个公共成员方法对象
Method getMethod(String name, Class<?>.. parameterTypes);
//4.返回单个成员方法对象
Method getDeclaredMethod(String name, Class<?>..parameterTypes);

//Method类中用于创建对象的方法
//参数一:用obj对象调用该方法
//参数二:调用方法的传递的参数(如果没有就不写)
//返回值:方法的返回值(如果没有就不写)
Object invoke(Object obj, Object... args);//运行方法

5. 利用反射获取类、字段、方法、方法参数中的注解

//1.获取类上多个注解(返回一个数组)
Annotation[] myAnnotations = clazz.getAnnotations();
//2.获取类上单个注解
Annotation annotation = clazz.getAnnotation(MyAnnotationCalss.class);
//3.获取方法上的注解
MyAnnotationMethod annotation = method.getAnnotation(MyAnnotationMethod.class);
//4.获取方法参数上的注解(返回的是二维数组)
Annotation[][] annotations = method.getParameterAnnotations();
//5.获取字段上的注解(返回多个注解)
Annotation[] annots = field.getAnnotations();
//6.获取字段上的注解(返回单个注解)
MyAnnotationField myAnnotationField = field.getAnnotation(MyAnnotationField.class);

标签:反射,Java,name,获取,注解,机制,方法,public,String
From: https://blog.csdn.net/weixin_39865508/article/details/142054380

相关文章

  • Java 设计模式-状态模式
    目录一.概述二.主要角色三.代码示例四.优缺点优点:缺点:五.常见应用场景一.概述        状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定的状态相关的行为放到一个类......
  • Java 设计模式-代理模式
    目录概述一.什么是代理模式1.举例说明二.代理模式作用1.保护代理2.增强功能3.代理交互4.远程代理:三.代理模式3个角色四.静态代理1.代码示例:五.JDK动态代理1.代码示例:六.CGLIB动态代理1.代码示例 七.JDK动态代理和CGLIB动态代理区别八.两种在......
  • [设计模式] Cola-StateMachine : 一个轻量实用的Java状态机框架
    1概述:状态机1.0状态机vs工作流在介绍状态机之前,先介绍一个工作流(WorkFlow),初学者通常容易将两个概念混淆。工作流(WorkFlow),大体是指业务过程(整体或者部分)在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的描述。在计算机系统中,工作流属于计算机支持的......
  • Dagger:Android 和 Java 的快速依赖注入框架
    在软件开发中,依赖注入(DI)是一种设计模式,用于实现控制反转,减少代码耦合,提高模块化。Dagger是一个由Google开发的依赖注入库,专门用于Android和Java应用程序,以其快速和高效著称。文章目录......
  • 力扣474-一和零(Java详细题解)
    题目链接:474.一和零-力扣(LeetCode)前情提要:因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。最近刚学完01背包,所以现在的题解都是以01背包问题为基础再来写的。如果大家不懂01背包的话,建议可以去学一学,01背包问题可以说是背包问题的基础。如果大家感兴趣,......
  • 06JAVA第一次考试选择
    判断正确1,不含公共类的JAVA源文件名称可以随便命名,不受任何限制。2,编译当前路径下的HelloWorld.java文件,使用的命令是:javacHelloWorld.java。3,JamesGosling是Java语言的创始人之一。4,Java语言的标识符区分大小写。5,java.lang包的Character类的isJavaIdentifierStart方......
  • Java中日期时间类的学习
    日期时间类目录日期时间类Date类(日期时间)SimpleDateFormat类(格式化)Calendar类(日历)Date类(日期时间)序号方法和描述1booleanafter(Datedate)若当调用此方法的Date对象在指定日期之后返回true,否则返回false。2booleanbefore(Datedate)若当调用此方法的Date......
  • 基于Java web社区公共安全管理系统(源码+lw+部署文档+讲解等)
    文章目录前言......
  • 基于Java技术的车辆故障管理软件的设计与实现(源码+lw+部署文档+讲解等)
    文章目录前言......
  • JAVA并发编程AQS原理剖析
    很多小朋友面试时候,面试官考察并发编程部分,都会被问:说一下AQS原理。面对并发编程基础和面试经验,专栏采用通俗简洁无废话无八股文方式,已陆续梳理分享了《一文看懂全部锁机制》、《JUC包之CAS原理》、《volatile核心原理》、《synchronized全能王的原理》,希望可以帮到大家巩固相......