Java之反射相关知识补充

news2024/11/23 23:51:39

Java之反射

  • 一、概述
    • 1、静态语言和动态语言
      • 1.1 静态语言
      • 1.2 动态语言
    • 2、Reflection(反射)
      • 2.1 介绍
      • 2.2 流程
      • 2.3 Java反射机制提供的功能
      • 2.4 优缺点
        • (1)优点
        • (2)缺点
      • 2.5 反射相关主要API
      • 2.6 示例
  • 二、反射相关操作
    • 1、获取Class类的实例
      • 1.1 已知具体的类,通过类的class属性获取(最安全可靠,程序性能高)
      • 1.2 已知某个类的实例,调用该实例的getClass()方法获取Class对象
      • 1.3 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
      • 1.4 内置基本数据类型可以直接用类名.Type
      • 1.5 利用ClassLoader
      • 1.6 样例
    • 2、有Class对象的类型
      • 2.1 相关类型
      • 2.2 示例
    • 3、类的加载过程
      • 3.1 加载
      • 3.2 链接
        • (1)验证
        • (2)准备
        • (3)解析
      • 3.3 初始化
      • 3.4 样例
    • 4、类的初始化
      • 4.1 类的主动引用(一定会发生类的初始化)
      • 4.2 类的被动引用(不会发生类的初始化)
      • 4.3 样例
    • 5、类加载器的作用
      • 5.1 类加载的作用
      • 5.2 类缓存
      • 5.3 类加载器的种类
        • (1)引导类加载器
        • (2)扩展类加载器
        • (3)系统类加载器
      • 5.4 样例
    • 6、获取运行时,类的完整结构
      • 6.1 获得类的名字
      • 6.4 获得类的属性
      • 6.5 指定属性的值
      • 6.6 类的方法
      • 6.7 获得指定方法
      • 6.8 获得构造器
      • 6.9 实例
    • 7、动态创建对象
      • 7.1 调用了类的无参构造器创建对象
      • 7.2 通过构造器创建对象
      • 7.3 通过反射调用普通方法
      • 7.4 通过反射操作属性
    • 8、获取泛型信息
    • 9、获取注解信息
      • 9.1 通过反射获得注解
      • 9.2 获得某个注解的value值
      • 9.3 获得某个指定的注解

一、概述

1、静态语言和动态语言

1.1 静态语言

运行时结构不可变的语言就是静态语言(如Java、C、C++)
Java不是动态语言,但Java可以称之为准动态语言。即Java有一定的动态性,可以利用反射机制获得类似动态语言的特性。Java的动态性让编程的时候更加灵活

1.2 动态语言

它是一类在运行时,可以改变其结构的语言。(如Object-C、C#、JavaScript、PHP、Python等)

2、Reflection(反射)

2.1 介绍

它是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

2.2 流程

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。也就是可以通过这个对象看到类的结构。这个对象就像一面镜子,透过镜子看到类的结构,所以形象地称为反射。

Class c = Class.forName("java.lang.String")

反射方式:实例化对象——>getClass()方法——>得到完整的“包类”名称

2.3 Java反射机制提供的功能

在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时获取泛型信息
在运行时调用任意一个对象的成员变量和方法
在运行时处理注解
生成动态代理
等等

2.4 优缺点

(1)优点

可以实现动态创建对象和编译,体现出很大灵活性。

(2)缺点

对性能有影响。使用反射基本上是一种解释操作,这类操作总是慢于直接执行相同的操作。

2.5 反射相关主要API

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器
等等

2.6 示例

package com.example.annotation;

import lombok.Data;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 反射
 */
@SpringBootTest
public class test3 {

    @Test
    public void test1() throws ClassNotFoundException {
        // 通过反射获取类的class对象
        Class c1 = Class.forName("com.example.annotation.User");
        System.out.println(c1);

        Class c2 = Class.forName("com.example.annotation.User");
        Class c3 = Class.forName("com.example.annotation.User");

        // 一个类在内存中只有一个class对象
        // 一个类被加载后,类的整个结构都会被封装在class对象中
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
    }
}

@Data
class User{
    private String name;
    private int id;
    private int age;
}

二、反射相关操作

1、获取Class类的实例

1.1 已知具体的类,通过类的class属性获取(最安全可靠,程序性能高)

Class c1 = User.class;

1.2 已知某个类的实例,调用该实例的getClass()方法获取Class对象

User user1 = new User();
Class c1 = user1.getClass();

1.3 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException

Class c1 = Class.forName("com.example.annotation.User");

1.4 内置基本数据类型可以直接用类名.Type

 Class c2 = Integer.TYPE;

1.5 利用ClassLoader

Class c3 = c1.getSuperclass();

1.6 样例

package com.example.annotation;

import lombok.Data;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 反射
 */
@SpringBootTest
public class test4 {

    @Test
    public void test1() throws ClassNotFoundException {
        User2 user = new Student();

        // 方式一:通过对象获得
        Class c1 = user.getClass();
        System.out.println(c1.hashCode());

        // 方式二:forname获得
        Class c2 = Class.forName("com.example.annotation.User2");
        System.out.println(c2.hashCode());

        // 方式三:通过类名.class获得
        Class c3 = User2.class;
        System.out.println(c3.hashCode());

        // 方式四:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4.hashCode());

        // 获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

@Data
class User2{
    String name;
    private int id;
    private int age;
}

class Student extends User2{
    public Student(){
        this.name = "学生";
    }
}

class Teacher extends User2{
    public Teacher(){
        this.name = "老师";
    }
}

在这里插入图片描述

2、有Class对象的类型

2.1 相关类型

class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类。
interface:接口
[]:数组
enum:枚举
annotation:注解@interface
primitive type:基本数据类型
void

2.2 示例

package com.example.annotation;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.xml.bind.Element;
import java.lang.annotation.ElementType;

@SpringBootTest
public class test5 {
    @Test
    public void test(){
        Class c1 = Object.class;  // 类
        Class c2 = Comparable.class; // 接口
        Class c3 = String[].class; // 一维数组
        Class c4 = int[][].class; // 二维数组
        Class c5 = Override.class; // 注解
        Class c6 = ElementType.class; // 枚举
        Class c7 = Integer.class; // 基本数据类型
        Class c8 = void.class; // void
        Class c9 = Class.class; // Class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);
    }
}

3、类的加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。

3.1 加载

将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象。

3.2 链接

将Java类的二进制代码合并到JVM的运行状态之中的过程。

(1)验证

确保加载的类信息符合JVM规范,没有安全方面的问题。

(2)准备

正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。

(3)解析

虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。

3.3 初始化

执行类构造器()方法的过程。类构造器()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)

3.4 样例

package com.example.annotation;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class test6 {

    @Test
    public void test(){
        A a = new A();
        System.out.println(a.m);
        /*
        1、加载到内存,会产生一个类对应Class对象
        2、链接,链接结束后 m = 0
        3、初始化,代码合并了
           <clinit>(){
               System.out.println("A类静态代码块初始化");
               m = 300;
               m = 100;
           }
           m = 100
         */
    }
}

class A{
    static {
        System.out.println("A类静态代码块初始化");
        m = 300;
    }

    static int m = 100;

    public A() {
        System.out.println("A类的无参构造初始化");
    }
}

在这里插入图片描述

4、类的初始化

4.1 类的主动引用(一定会发生类的初始化)

(1)当虚拟机启动,先初始化main方法所在的类
(2)new一个类的对象
(3)调用类的静态成员(除了final常量)和静态方法
(4)使用java.lang.reflect包的方法对类进行反射调用
(5)当初始化一个类,如果其父类没有被初始化,则会先初始化它的父类

4.2 类的被动引用(不会发生类的初始化)

(1)当访问一个静态域时,只有真正声明这个域的类才会被初始化。(当通过子类引用父类的静态变量,不会导致子类初始化)
(2)通过数组定义类引用,不会触发此类的初始化
(3)引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)

4.3 样例

package com.example.annotation;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class test7 {
    static {
        System.out.println("Main类被加载");
    }

    @Test
    public void test() throws ClassNotFoundException {
        // 1、主动引用
        Son son = new Son();

        // 2、反射也会产生主动引用
        Class.forName("com.example.annotation.Son");

        // 不会产生类的引用的方法
        System.out.println(Son.b);

        Son[] array = new Son[5];

        System.out.println(Son.M);
    }

}

class Father{
    static int b = 2;

    static {
        System.out.println("父类被加载");
    }
}

class Son extends Father{
    static {
        System.out.println("子类被加载");
        m = 300;
    }

    static int m = 100;
    static final int M = 1;
}

5、类加载器的作用

5.1 类加载的作用

将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。

5.2 类缓存

标准的JavaSE类加载器可以按照要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象。

5.3 类加载器的种类

(1)引导类加载器

用C++编写,是JVM自带的类加载器,负责Java平台核心库,用来装载核心类库。该加载器无法直接获取。

(2)扩展类加载器

负责jre/lib/ext目录下的jar包或 java.ext.dirs指定目录下的jar包装入工作库。

(3)系统类加载器

负责java-classpath或 java.class.path所指的目录下的类与jar包装入工作,是最常用的加载器。

5.4 样例

package com.example.annotation;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class test8 {

    @Test
    public void test1() throws ClassNotFoundException {

        // 获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        // 获取系统类加载器的父类加载器(扩展类加载器)
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        // 获取扩展类加载器的父类加载器(根加载器(c/c++))
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        // 测试当前类是哪个加载器加载的
        ClassLoader classLoader = Class.forName("com.example.annotation.test1").getClassLoader();
        System.out.println(classLoader);

        // 测试jdk内置的类
        classLoader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader);

        // 如何获得系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));
        
    }
}

在这里插入图片描述

6、获取运行时,类的完整结构

通过反射,获取运行时类的完整结构

6.1 获得类的名字

// 获得类完整的路径名
c1.getName()

// 获得类的名字
c1.getSimpleName()

6.4 获得类的属性

// 只能找到public属性
Field[] fields = c1.getFields();  

// 可以找到全部属性
Field[] fields2 = c1.getDeclaredFields(); 

// 输出所有属性
for (Field field : fields2) {
     System.out.println(field);
}

6.5 指定属性的值

// 指定属性的值
Field name = c1.getDeclaredField("name");

6.6 类的方法

// 获得本类及其父类的全部public方法
Method[] methods = c1.getMethods();

// 获得本类的所有方法
Method[] methods2 = c1.getDeclaredMethods();

6.7 获得指定方法

// 重载
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);

6.8 获得构造器

// 获得全部public方法
Constructor[] constructors = c1.getConstructors();

// 获得本类的所有方法
Constructor[] constructors2 = c1.getDeclaredConstructors();

6.9 实例

package com.example.annotation;

import lombok.Data;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

@SpringBootTest
public class test9 {

    @Test
    public void test1() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        User3 user = new User3();
        Class c1 = user.getClass();

        // 获得类的名字
        System.out.println("=================类的名字======================");
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());

        // 获得类的属性
        System.out.println("=================类的属性======================");
        Field[] fields = c1.getFields();  // 只能找到public属性

        Field[] fields2 = c1.getDeclaredFields(); // 可以找到全部属性
        for (Field field : fields2) {
            System.out.println(field);
        }

        // 获得指定属性的值
        System.out.println("=================指定属性的值======================");
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

        // 获得类的方法
        System.out.println("=================类的方法======================");
        // 获得本类及其父类的全部public方法
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println("正常的:" + method);
        }

        // 获得本类的所有方法
        methods = c1.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("getDeclaredMethods" + method);
        }

        // 获得指定方法
        // 重载
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        // 获得构造器
        System.out.println("=================获得指定构造器======================");
        // 获得全部public方法
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        // 获得本类的所有方法
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
    }

}

@Data
class User3 {
    String name;
    private int id;
    private int age;
}

7、动态创建对象

7.1 调用了类的无参构造器创建对象

创建类的对象:调用Class对象的newInstance()方法
(1)类必须有一个无参数的构造器。
(2)类的构造器的访问权限需要足够。

// 获得Class对象
Class c1 = Class.forName("com.example.annotation.User4");

// 构造一个对象
// 本质是调用了类的无参构造器
User4 user4 = (User4)c1.newInstance();
System.out.println(user4);

在这里插入图片描述

7.2 通过构造器创建对象

(1)通过Class类的getpeclaredConstryctor(Class … parameterTypes)取得本类的指定形参类型的构造器。
(2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
(3)通过Constructor实例化对象

// 通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User4 user5 = (User4)constructor.newInstance("张三",1,2);
System.out.println(user5);

在这里插入图片描述

7.3 通过反射调用普通方法

通过反射,调用类中的方法,通过Method类完成。
(1)通过Class类的getMethod(String name,Class… parameterTypes)方法取得一个Method对象并设置此方法操作时所需要的参数类型。
(2)之后使用Objedt invoke(Object obj, 0bject[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

// 通过反射调用普通方法
User4 user6 = (User4)c1.newInstance();

// 通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
// invoke:激活
// (对象,”方法的值“)
setName.invoke(user6, "李四");
System.out.println(user6.getName());

在这里插入图片描述

7.4 通过反射操作属性

Method和Field、 Constructor对象 都有setAccessible()方法。
setAccessible作用是启动和禁用访问安全检查的开关。
(1)参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么设置为true,使得原本无法访问的私有成员也可以访问。
(2)参数值为false则指示反射的对象应该实施Java语言访问检查。

// 通过反射操作属性
User4 user5 = (User4) c1.newInstance();
Field name = c1.getDeclaredField("name");
// 不能直接操作私有属性,需要关闭程序的安全检测,属性或方法的setAccessible(true)
name.setAccessible(true);
name.set(user5,"王五");
System.out.println(user5.getName());

在这里插入图片描述

8、获取泛型信息

反射操作泛型,Java采用泛型擦除的机制来引入泛型,Java中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换问题,但是,一旦编译完成,所有和泛型有关的类型全部擦除。
为了通过反射操作这些类型, Java新增了ParameterizedType , GenericArrayType、TypeVariable 和WildcardType 几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型。
(1)ParameterizedType :表示一种参数化类型,比如Collection
(2)GenericArrayType :表示一种元素类型是参数化类型或者类型变量的数组类型
(3)TypeVariable :是各种类型变量的公共父接口
(4)WildcardType :代表一种通配符类型表达式

9、获取注解信息

9.1 通过反射获得注解

// 通过反射获得注解
Annotation[] annotations = c1.getAnnotations();

9.2 获得某个注解的value值

// 获得某个注解的value值
Field[] f = Class.class.getDeclaredFields();
String value = f[0].getAnnotation(Alias.class).value();

9.3 获得某个指定的注解

// 获得某个类指定的注解
Alias f = c1.getDeclaredField("id").getAnnotation(Alias.class);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/20901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第十二节:String类【java】

目录 &#x1f4d8;1.1 字符串构造方法 &#x1f4d2;1.2 String对象怎样比较 &#x1f4dc;1.2.1 引用类型 比较的是引用中的地址。 &#x1f4c4;1.2.2 boolean equals(Object anObject) 方法&#xff1a;比较怕两个引用所指的对象当中的内容是否一致 &#x1f4d1;1.2…

企业级nginx使用

企业级nginx使用 nginx实现平滑升级 [rootlnmp nginx-1.16.0]# cd /usr/local/nginx/sbin/ [rootlnmp sbin]# ls nginx nginx.old [rootlnmp sbin]# ./nginx -v nginx version: nginx/1.16.0 [rootlnmp sbin]# ./nginx.old -v nginx version: nginx/1.14.2 [rootlnmp sbin]#操…

物联网开发笔记(49)- 使用Micropython开发ESP32开发板之控制RGB全彩LED模块

一、目的 这一节我们学习如何使用我们的ESP32开发板来控制RGB全彩LED模块。 二、环境 ESP32 RGB全彩LED模块 Thonny IDE 几根杜邦线 1&#xff0c;共阴极接线方法 2&#xff0c;共阳极接线方法 三、代码 1&#xff0c;亮指定的颜色&#xff0c;比如百度蓝。 我们使用取色…

万字长文,精美插图,带你玩转redis

资料下载&#xff1a; 链接: https://pan.baidu.com/s/1ue4Bnv4b4ifp0S0I_yOJ_w?pwdd9x9 提取码: d9x9 Redis学习笔记 1. 认识Redis 1.1 什么是NoSQL&#xff1f; SQL是关系型数据库&#xff0c;NoSQL是非关系型数据库 下面是几种非关系型数据库及其优缺点和应用场景。 分类…

[附源码]java毕业设计网上书店系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【分隔结构】动宾分离

动宾分离 动词 宾语 状语&#xff1a;如果宾语较长&#xff0c;状语较短&#xff0c;会转化为 动词 状语 宾语 While I disapprove of what you say, I would defend to the death your right to say it. 名词 引导词 主语 及物动词 You are the man that I will marry…

【K8S】学习笔记(一)

K8S学习笔记一、Kubernetes1.1、K8S功能1.2、K8S架构组件1.2.1、架构细节1.3、K8S核心概念1.3.1、Pod1.3.2、Volume1.3.3、Controller1.3.4、Deployment1.3.5、Service1.3.6、Label1.3.7、Namespace1.3.8、API二、搭建K8S2.1、K8S搭建规划2.1.1、单master集群2.1.2、多master集…

Html5的新增特性

Html5的新增特性主要是针对以前的不足&#xff0c;增加了一些新的标签&#xff0c;新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是IE9以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新特性。 声明&#xff1…

m基于迫零ZF准则的通信均衡器的matlab仿真

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 在数字通信系统中&#xff0c;码间串扰和加性噪声是造成信号传输失真的主要因素&#xff0c;为克服码间串扰&#xff0c;在接收滤波器和抽样判决器之间附加一个可调滤波器&#xff0c;用…

STM32CubeMX:串口DMA

DMA&#xff1a;直接储存区访问&#xff0c;DMA传输将数据从一个地址空间复制到另一个空间。DMA传输方式无需CPU直接控制传输&#xff0c;也没有中断处理方式那样保留现场和恢复现场过程&#xff0c;通过硬件为RAM何IO设备开辟一条直接传输数据的通道&#xff0c;从而可以提高C…

WSL下安装ubuntu 18.04 +meep进行FDTD仿真计算

WSL下安装ubuntu 18.04 meep进行FDTD仿真计算前言WSL安装过程打开虚拟环境下载Ubuntu并修改安装路径更改软件源MeepVScode远程访问测试程序前言 使用meep进行FDTD开发&#xff0c;开源。这里记录一下自己的安装过程&#xff0c;可以不安装在C盘&#xff0c;有助于后面进行修改…

【JVM】java的jvm类加载器和类加载子系统

JVM类加载器和类加载子系统一、JVM体系结构二、ClassLoader类介绍三、类加载子系统3.1 加载阶段3.1.1 引导类加载器&#xff08;Bootstrap ClassLoader&#xff09;3.1.2 扩展类加载器&#xff08;Extension ClassLoader&#xff09;3.1.3 应用程序类加载器&#xff08;Applica…

Android入门第32天-Android中的Alert Dialog的使用大全

写在我的第200篇博客中的“前言” 这篇是我的第200篇博客。落笔写正文前我感触彼深。自从一个小P孩那时写博客只是为了一时的好玩&#xff0c;到逐步发觉只有让越来越多的人理解了技术&#xff0c;把技术普及到门槛越来越低&#xff0c;才会反推技术人员的处镜越来越好。因为必…

Allegro如何输出STP文件操作指导

Allegro如何输出STP文件操作指导 Stp文件用于查看实物,Allegro支持输出STP格式的文件,下面介绍如何输出,操作步骤如下 选择File-export-STEP 根据自己的需要选择参数 如果需要输出电气过孔,选electronic hole,需要外层铜皮,勾选External Copper 常规默认值就可以了,…

UE5笔记【六】流明引擎Lumen简介;Lumen处理发光物体。

RealTimeGlobal illumination System。实时全局照明系统。 打开Lumen 从设置中&#xff0c;打开【项目设置】往下找【渲染Render】 然后再GI中将途中两项选择为Lumen。 同时需要一个后期处理量PostProcessVolume。刚好场景中有。 需要勾选【全局光照GI】中的【方法】选定为【…

Spring七天速成:入门必看(二)

-----持续更新Spring入门系列文章----- 如果你也喜欢Java和算法&#xff0c;欢迎订阅专栏共同学习交流&#xff01; 你的点赞、关注、评论、是我创作的动力&#xff01; -------希望我的文章对你有所帮助-------- 前言&#xff1a; 在前篇文章当中我们已经大概了解了Spring的…

QT布局之QGridLayout嵌套QHBoxLayout

搞嵌入式系统开发的&#xff0c;往往都是真全栈开发者。从硬件到驱动到操作系统到应用以及功能界面&#xff0c;是哪里需要搞哪里。这不&#xff0c;最近需要开发一个基于QT的界面功能&#xff0c;涉及到控件布局。因为不熟悉&#xff0c;走了一些弯路。这里将相关调试记录下来…

计算机网络面试题【面试】

计算机网络面试题前言OSI 七层网络模型应用层表示层会话层传输层网络层数据链路层物理七层总结输入URL后会发生什么1. DNS域名解析2. 三次握手建立TCP连接3. 发送HTTP网络请求4. 服务器处理请求5. 服务器返回响应6. 四次挥手断开TCP连接7. 解析HTMLDNS解析过程DNS解析&#xff…

Froala Editor JavaScript WYSIWYG HTML 编辑器

Froala Editor JavaScript WYSIWYG HTML 多用途、易于使用的 WYSIWYG 编辑器&#xff0c;优雅 每次点击&#xff0c;我们都会让网络编辑变得更简单、更强大、更愉快 安全、快速、智能和稳健。 Froala Editor 是一个 用 JavaScript 编写 的轻量级 WYSIWYG HTML 编辑器&#xff0…

【计算机毕业设计】小型OA系统设计与实现Springboot

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括小型OA系统设计与实现的网络应用&#xff0c;在国外小型OA系统设计与实现已经是很普遍的方式&#xff0c;不…