Java虚拟机之类加载机制

反激开关电源设计全解析:从CCM/DCM原理到PCB布局实战 开关电源作为现代电子设备的能量转换核心,其核心原理是通过高频开关动作实现高效的电能变换。反激拓扑因其结构简单、成本低廉且易于实现电气隔离,成为小功率离线式电源的主流选择。其技术价值在于通过变压器耦合实现能量存储与传递,解决了安全隔离与多路输出等关键需求,广泛应用于充电器、适配器及家电供电等场景。本文聚焦反激电路,深入剖析其CCM与DCM两种工作模式的原理差异及选型考量,并结合伏秒平衡定律与RCD钳位等热词,详解从变压器计算到MOSFET选型的完整工程设计流程。 阅读详情

类是在运行期间第一次使用时动态加载的,而不是一次性加载所有类。因为如果一次性加载,那么会占用很多的内存。

目录

1.类的生命周期

2.类加载过程

3.类初始化时机

1.主动引用

2.被动引用

4.类加载器分类

Java 虚拟机的角度:

Java开发人员的角度:

双亲委派模型:


1.类的生命周期

 

包括以下 7 个阶段:

  • 加载(Loading)
  • 验证(Verification)
  • 准备(Preparation)
  • 解析(Resolution)
  • 初始化(Initialization)
  • 使用(Using)
  • 卸载(Unloading)

2.类加载过程

包含了加载、验证、准备、解析和初始化这 5 个阶段。

(1)加载

加载是类加载的一个阶段

加载过程完成以下三件事:

  • 通过类的完全限定名称获取定义该类的二进制字节流。
  • 将该字节流表示的静态存储结构转换为方法区的运行时存储结构。
  • 在内存中生成一个代表该类的 Class 对象,作为方法区中该类各种数据的访问入口。

其中二进制字节流可以从以下方式中获取:

  • 从 ZIP 包读取,成为 JAR、EAR、WAR 格式的基础。
  • 从网络中获取,最典型的应用是 Applet。
  • 运行时计算生成,例如动态代理技术,在 java.lang.reflect.Proxy 使用 ProxyGenerator.generateProxyClass 的代理类的二进制字节流。
  • 由其他文件生成,例如由 JSP 文件生成对应的 Class 类。

(2)验证

确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

(3)准备

类变量是被 static 修饰的变量,准备阶段为类变量分配内存并设置初始值,使用的是方法区的内存。

实例变量不会在这阶段分配内存,它会在对象实例化时随着对象一起被分配在堆中。应该注意到,实例化不是类加载的一个过程,类加载发生在所有实例化操作之前,并且类加载只进行一次,实例化可以进行多次。

//初始值一般为 0 值,例如下面的类变量 value 被初始化为 0 而不是 123。
public static int value = 123;

//常量 value 被初始化为 123 而不是 0。
public static final int value = 123;

(4)解析

将常量池的符号引用替换为直接引用的过程。

解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。

 

#初始化阶段

初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。

静态语句块只能访问到定义在它之前的类变量,定义在它之后的类变量只能赋值,不能访问。

//父类的 <clinit>() 方法先执行,也就意味着父类中定义的静态语句块的执行要优先于子类
static class Parent {
    public static int A = 1;
    static {
        A = 2;
    }
}

static class Sub extends Parent {
    public static int B = A;
}

public static void main(String[] args) {
     System.out.println(Sub.B);  // 2
}

接口中不可以使用静态语句块,但仍然有类变量初始化的赋值操作,因此接口与类一样都会生成 <clinit>() 方法。但接口与类不同的是,执行接口的 <clinit>() 方法不需要先执行父接口的 <clinit>() 方法。只有当父接口中定义的变量使用时,父接口才会初始化。另外,接口的实现类在初始化时也一样不会执行接口的 <clinit>() 方法。

虚拟机会保证一个类的 <clinit>() 方法在多线程环境下被正确的加锁和同步,如果多个线程同时初始化一个类,只会有一个线程执行这个类的 <clinit>() 方法,其它线程都会阻塞等待,直到活动线程执行 <clinit>() 方法完毕。如果在一个类的 <clinit>() 方法中有耗时的操作,就可能造成多个线程阻塞,在实际过程中此种阻塞很隐蔽

 

3.类初始化时机

1.主动引用

虚拟机规范中并没有强制约束何时进行加载,但是规范严格规定了有且只有下列五种情况必须对类进行初始化(加载、验证、准备都会随之发生):

  • 遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行过初始化,则必须先触发其初始化。最常见的生成这 4 条指令的场景是:使用 new 关键字实例化对象的时候;读取或设置一个类的静态字段(被 final 修饰、已在编译期把结果放入常量池的静态字段除外)的时候;以及调用一个类的静态方法的时候。
  • 使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行初始化,则需要先触发其初始化。
  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含 main() 方法的那个类),虚拟机会先初始化这个主类;
  • 当使用 JDK 1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果为 REF_getStatic, REF_putStatic, REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化;

2.被动引用

所有引用类的方式都不会触发初始化,称为被动引用

  • 通过子类引用父类的静态字段,不会导致子类初始化。
  • 通过数组定义来引用类,不会触发此类的初始化。该过程会对数组类进行初始化,数组类是一个由虚拟机自动生成的、直接继承自 Object 的子类,其中包含了数组的属性和方法。
  • 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。

类和类加载器

两个类相等,需要类本身相等,并且使用同一个类加载器进行加载。这是因为每一个类加载器都拥有一个独立的类名称空间。

这里的相等,包括类的 Class 对象的 equals() 方法、isAssignableFrom() 方法、isInstance() 方法的返回结果为 true,也包括使用 instanceof 关键字做对象所属关系判定结果为 true。

4.类加载器分类

Java 虚拟机的角度:

1.启动类加载器, C++ 实现,是虚拟机自身的一部分;

2.所有其他类加载器, Java 实现,独立于虚拟机,继承自抽象类 java.lang.ClassLoader。

Java开发人员的角度:

1.启动类加载器:此类加载器负责将存放在 <JRE_HOME>\lib 目录中的,或者被 -Xbootclasspath 参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录中也不会被加载)类库加载到虚拟机内存。中。

2.扩展类加载器:是由 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将 <JAVA_HOME>/lib/ext 或者被 java.ext.dir 系统变量所指定路径中的所有类库加载到内存中,开发者可以直接使用扩展类加载器。

3.应用程序类加载器:由 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此一般称为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

双亲委派模型:

要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。这里的父子关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)

 

工作过程

一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时才尝试自己加载。

好处

使得 Java 类随着它的类加载器一起具有一种带有优先级的层次关系,从而使得基础类得到统一。

实现

public abstract class ClassLoader {
    // The parent class loader for delegation
    private final ClassLoader parent;

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

// loadClass()先检查类是否已经加载过,如果没有则让父类加载器去加载。
//当父类加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。

public abstract class ClassLoader {
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    c = findClass(name);
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
}

自定义加载器实现

// FileSystemClassLoader 是自定义类加载器,继承自 java.lang.ClassLoader,
//用于加载文件系统上的类
//它首先根据类的全名在文件系统上查找类的字节代码文件(.class 文件),然后读取该文件内容
//最后通过 defineClass() 方法来把这些字节代码转换成 java.lang.Class 类的实例
public class FileSystemClassLoader extends ClassLoader {

    private String rootDir;

    public FileSystemClassLoader(String rootDir) {
        this.rootDir = rootDir;
    }
//重写 findClass() 方法。
//java.lang.ClassLoader 的 loadClass() 实现了双亲委派模型的逻辑,自定义类加载器一般不去重写它

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = getClassData(name);
        if (classData == null) {
            throw new ClassNotFoundException();
        } else {
            return defineClass(name, classData, 0, classData.length);
        }
    }

    private byte[] getClassData(String className) {
        String path = classNameToPath(className);
        try {
            InputStream ins = new FileInputStream(path);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            int bytesNumRead;
            while ((bytesNumRead = ins.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesNumRead);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String classNameToPath(String className) {
        return rootDir + File.separatorChar
                + className.replace('.', File.separatorChar) + ".class";
    }
}

 

 

HFSS与AI融合:智能算法如何重塑天线设计流程 本文探讨了HFSS与AI融合如何通过智能算法革新天线设计流程。在5G/6G通信时代,AI技术如机器学习和遗传算法显著提升了高频电磁场仿真效率,将传统设计周期从数周缩短至数小时,并优化了天线性能。文章详细介绍了AI与HFSS的集成策略、关键技术突破及典型应用案例,展示了智能算法在天线设计中的巨大潜力。 阅读详情

相关推荐

深度解析:如何通过NodeRed实现私有485协议VRF中央空调与HomeAssistant的无缝对接

本文详细介绍了如何利用NodeRed的灵活流程化编程,破解并处理VRF中央空调的私有485协议,实现与HomeAssistant的无缝本地化集成。文章从协议分析、硬件准备到NodeRed核心流程搭建、数据映射及双向通信控制,提供了一套完整的实战方案,帮助用户将非标设备深度融入智能家居生态,摆脱对厂家云服务的依赖。

weixin_29173777的博客 408

Java虚拟机之类加载机制原理详解

1 JVM基本概念 1.1 概述    JVM是可运行Java代码的虚拟计算机,JVM是运行在操作系统之上的,它与硬件没有直接的交互。JVM说到底,其实就是在物理机上运行的程序,同时他依托物理机而拥有了完善的硬件架构和指令系统。 1.2 运行过程   Java源文件,通过编译器,能够生产相应的.Class文件,也就是字节码文件,而字节码文件又通过Java虚拟机中的解释器,编译成特定机器上的机器码 。也就是如下:    • Java源文件—->编译器—->字节码文件    • 字节码文件

qq_39164234的博客 1686

AutoDL跑yolo

由于博主在AutoDL的JupyterLab的终端直接上传ZIp文件要么老是再上传中被中断,要么就是上传后使用unzip指令解压显示“找不到”,作为纯小白的我实在太难了!这个文件列出了一个 Python 项目所需的所有依赖包及其精确的版本号。这个文件是 Python 项目中常见的一种方式,用于确保项目在不同环境中都能以相同的依赖包配置运行。3.进入JupyterLab,在文件夹目录中找到上传的文件夹,右键点击“复制路径”。然后在终端中输入以下指令进行切换到该文件夹路径。9.安装成功后开始输入指令开跑!

m0_73804659的博客 1206

java虚拟机jvm之类加载机制

java类的加载过程、java虚拟机、jvm、类型的加载、连接和初始化过程、hotspot虚拟机

qq_33014341的博客 348

C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照

C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照下面进行详细步骤说明,感兴趣的同学可以看一下: 1简单示例(一条线): 2.数据源随着时间不断变化,进度条变化 。多条线: 3.看在整段时期内的数据大体图(消去或出现)进度条: 4.后台将时刻记录变化记录到一个txt文本里以供详细校验: 话不多说上码: using System; using Sys...

帅boy的博客 4308

HLM(多层线性模型)在stata中语句

在阅读CEPS中发现有些研究采用的是HLM模型,HLM简单来说用一个方程跑两个回归。举例,对学习成绩影响因素,不同层有不同的影响,如在个体层面上个体特征会对成绩产生影响,在学校层面学校排名等因素会对成绩产生影响,两种因素不在一个层面,每层造成的差异都不相同。 在找相关语句时候发现操作这个语句的软件大多是SPSS和HLM,对于stata操作者并不友好。因此,在有限资料中总结了HLM在stata中的语句,后面会附上学习视频和链接。 先放语句,后面对方程式一个大致解析。由于针对HLM有一本书的介绍,可能一篇文章无

weixin_44652251的博客 1万+

《Java虚拟机》之类加载机制

一.类加载的时机 类从被加载到虚拟机内存开始,到卸载出内存为止,大致的生命周期为:加载(loading)-&gt;验证(Verification)-&gt;准备(Preparation)-》解析(Resolution)-》初始化(Initialization)-&gt;使用(Using)-》卸载(Unloading)等七个阶段。 在这当中,加载,验证,准备,初始...

soulstones的博客 203

【定位模块项目实战】gnss_localizer、lidar_localizer功能包解析

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、1.2.3.4.二、1.2.3.4.三、1.2.3.4.四、1.2.3.4.总结参考资料 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对**【无人驾驶autoware项目实战】感知–定位模块**做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章 提示:以下是本篇文章正文内容 一、 1. 2. 3. 4. . . 二、

qq_35635374的博客 1931

深入理解Java虚拟机之类加载机制

概述虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。类型的加载、连接和初始化都是在运行期间完成的。类加载的时机整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载。其中验证、准备、解析统称为连接。 加载、验证、准备、初始化、卸载这5部分顺序是确定的。而解析可以在初始化后执行,为了支持j

yuyurenjie的博客 1192

OceanBase容量统计:租户、数据库、表大小

🍎 数据库版本:OceanBase V4。

Sebastien23的博客 1400

metahuman 下载材质 脸部灰白 脸部过亮

metahuman 下载材质 脸部灰白 脸部过亮

jacke121的专栏 243

深入理解Java虚拟机之类加载机制篇

概述 ​ 虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,就是虚拟机的类加载机制。 ​ 在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种策略虽然增加了类加载时系统额外的开销,但是能给 Java 应用程序提供高度的灵活性,Java 的动态扩展优势就依赖于运行期动态加载和动态连接来实现的。例如用户可以在编写一个面向接口的应用程序时,可以等到运行时再指定具体的实现类,还可以通过 Java 预定义的和

潇歌的博客 2763

【银河麒麟V10】【桌面】【服务器】系统启动问题

1、如果之前运行好好的,重启后系统报错,一般80%是因为fstab的问题,回想下之前有没有添加过外接存储,修改过/etc/fstab,如果是的话一般是因为存储异常(比如网络存储无法连接,本地存储路径变化)导致系统开机自检失败,导致无法正常启动; 处理方式:进入单用户(单用户进入的几种方式上面有专门文章介绍),修改/etc/fstab,将新增的内容暂时注释掉,然后重启系统,能正常进入系统后再分析失败原因。 ...

桂安俊@KylinOS 3万+

java虚拟机之类加载机制

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是java虚拟机的类加载机制。 这是会思考两个问题: 一,什么时候会进行类加载? 在Java中,类型的加载是在程序运行期间完成的,而且是按需加载,只会加载一次,以后从虚拟机的class实例的缓存中获取。 二,用什么去加载? 类

sugar-foxs 275

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

JVM_java虚拟机之类加载机制

1 什么是类的加载? 类的加载: 指的是将类的.class文件中的二进制数据读入到内存中,并转换成java.lang.Class类的一个实例. .class文件:大家应该都很熟悉了, 我们写好的代码文件后缀是.java文件. 将.java文件编译后就会变成.class文件了. 2:类加载的过程 类加载的过程也可以称为(类的生命周期):小括号内的三部分统称为:连接 加载 -> ( 验证 -> 准备 -> 解析 ) -> 初始化 ...

wang5701071的博客 300

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java虚拟机之类加载机制(一)

一.首先先说一下java虚拟机的生命周期: 1.执行了system.exit(); 2.程序正常执行结束; 3.程序在执行过程中遇到了异常或错误而终止; 4.由于操作系统出现错误而导致java虚拟机进程终止; 二:ClassLoader 1.几种类加载器: (1).Bootst...

chuangangliu8460的博客 78

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java虚拟机类加载机制浅谈_浅谈Java虚拟机(三)之类加载机制

在《浅谈Java虚拟机》这篇文章中,我们提到了JVM从操作系统方面来说,可以将其看做是一个进程,分别有类加载器子系统,执行引擎子系统和垃圾收集子系统。这一篇文章就简单的来谈一下类加载器子系统中的类加载机制。第一:什么叫做类加载机制就是JVM把.class字节码文件加载到内存中,并对其数据进行校验、准备、解析和初始化,最终形成能够被JVM可以直接拿来使用的java类型的一个过程,叫做类加载。如图示:...

weixin_42127748的博客 239

深入理解 Java 虚拟机之类加载机制篇

中,虽然加载、验证、准备、初始化和卸载这 5 个阶段的顺序是确定的,但是类的加载过程并不是一定会按照这些顺序执行的,这些阶段都是互相交叉地混合式进行的,通常会在一个阶段执行的过程中调用、激活另外一个阶段;解析阶段在某些情况下可以在初始化阶段进行时,再进行解析,为了能够满足 Java 语言的运行时绑定(动态绑定) ? Java 虚拟机规范并没有强制确定类加载过程的第一个阶段是加载,这主要取决于虚拟机的具体实现。但对于初始化阶段,虚拟机规范明确规定了面临这以...

weixin_70730532的博客 190

java虚拟机加载类_java虚拟机之类加载机制(一)

一.首先先说一下java虚拟机的生命周期:1.执行了system.exit();2.程序正常执行结束;3.程序在执行过程中遇到了异常或错误而终止;4.由于操作系统出现错误而导致java虚拟机进程终止;二:ClassLoader1.几种类加载器:(1).Bootstrap ClassLoader:这个主要加载JVM自身工作需要的类,是由JVM自己控制的,需要加载哪个类,怎么加载都是有JVM负责的!别...

weixin_39977276的博客 66

回顾《深入理解 Java 虚拟机》之类加载机制

虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制。 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段: 除却解析之外,其他各个阶段都是严格按顺序执行的,解析则不一定,为了支持 Java 的运行时绑定特性,它有时在初...

旧时光 | YoungChen's 博客 364

深入理解java虚拟机之类加载机制

回顾我们《深入理解java虚拟机之初识JVM》这篇文章https://blog.youkuaiyun.com/mulinsen77/article/details/84391796,我们了解了类加载的过程,我们知道了类加载的生命周期有以下七个阶段:加载、验证、准备、解析、初始化、使用、卸载。其中解析和初始化交换顺序可以实现动态绑定。 类初始化的时机:(类初始化的时候加载验证准备也会随着发生) JVM规范中严...

mulinsen77的博客 441

Java虚拟机JVM之类加载机制与类加载器

一、类的生命周期 类的生命周期 加载 --> 验证 --> 准备 --> 解析 --> 初始化 --> 使用 --> 卸载 |<------- 连接 ------->| |<------------- 类加载 ---------------->| 类的生命周期一共有 7 个阶段,其中前五个阶段较为重要,统称为类加...

qq_37776015的博客 444
上一篇: Java虚拟机之内存分配与回收策略
下一篇: JavaIO(一)分类、磁盘操作、字节操作、字符操作
trytrylmt
博客等级 码龄9年 7粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值