深入Java类加载器

PLC期末速成——顺序功能图转梯形图 一、根据顺序功能图写出梯形图程序 顺序功能图: 梯形图: 1、程序段1,系统运行标志M0.0的启-保-停控制电路。 2、程序段2,PLC上电与逆行,初始化脉冲M1.0激活初始化步M2.0。 3、程序段3,当M2.0初始化步为活动步,并且M0.0系统运行标志位为1时,置位M2.1步,复位M2.0步。 4、当M2.1为活动步,并且I0.3中液位传感器为1时,置位M2.2步,复位M2.1步。 5、程序段5,当M2.2为活动步,并且I0.2高液位传感器为1时,置位M2.3步,复位M2.2步。 6、程序段 阅读详情

深入Java类加载器

类加载器原理

  • 类加载器的作用
    - 将class文件字节码内容加载到内存中,并将这些静态数据转化成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法取类数据的访问入口
  • 类缓存
    • 标准的Java SE类加载器可以按照要求加载类,但一旦某个类被加载到类加载器中,它将维持一段时间(缓存)。不过,JVM垃圾收集器可以回收这些Class对象

类加载器层次结构(树状结构)

  1. 引导类加载器(bootstrap class loader)
    • 它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar, 或sun.boot.class.path路径下的内容),是用原生代码实现的,并不继承自java.lang.ClassLoader
    • 加载扩展类加载器和应用程序类加载器,并指定他们的父类加载器。
  2. 扩展类加载器(extensions class loader)
    • 用来加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar, 或 java.ext.dirs 路径下的内容)。java 虚拟机的实现会提供一个扩展库目录。该类加载器在该目录中查找并加载 Java 类。
    • 由 sun.misc.Launcher$ExtClassLoader 实现
  3. 应用程序类加载器(application class loader)
    • 它根据 Java 应用的类路径( class , java.class.path 路径下的内容),一般来说 java 应用的类都是由它来完成加载的
    • 由 sun.misc.Launcher$AppClassLoader 实现
  4. 自定义类加载器
    • 开发人员可以通过继承 java.lang.ClassLoader 类的方式实现自己的类加载器,以满足一些特殊的需求

图示:(并不是继承关系,而是组合)

Created with Raphaël 2.1.0 自定义类加载器...应用程序类加载器(application class loader)扩展类加载器(extensions class loader)引导类加载器(bootstrap class loader)

java.lang.ClassLoader 类介绍

  • 作用:
    • java.lang.ClassLoader 类的基本职责就是根据一个指定类的名称,找到或者生成其对应的字节代码,让后从这些字节代码中定义出一个 Java 类,即 java.lang.ClassLoader 的一个实例。
    • 除此之外,ClassLoader 还负责加载 Java 应用所需要的资源,如图像文件和配置文件等。
  • 相关方法:
    • 参阅 JDK 文档
      • 对于这些方法表示类名称的 name 参数的值是二进制名称。需要注意的是内部类的表示。如:com.sample.Sample$1 和 com.sample.Sample$Inner等表示方式

类加载器的代理模式

  • 代理模式
    • 交给其他加载器来加载指定的类
  • 双亲委托机制
    • 就是某一个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次追溯,直到最高的爷爷辈的,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成加载任务时,才自己去加载
    • 双亲委托机制是为了保证 Java 核心库的安全。
      • 这种机制就保证不会出现用户自己能定义 java.lang.Object 类的情况
    • 类加载器除了用于加载类,也是安全的最基本屏障。
  • 双亲委托机制是代理模式的一种
    • 并不是所有的类加载器都采用双亲委托机制。
    • Tomcat 服务器类加载器也使用代理模式, 所不同的是它是首先去尝试加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。

自定义类加载器(文件、网络、加密)

自定义类加载器流程:

  1. 继承 java.lang.ClassLoader
  2. 首先检查请求的类型是否已经被这个类加载器加载到命名空间中去了,如果已经装载,直接返回;
  3. 委托类加载请求给父类加载器,如果父类加载器能够完成,则返回父类加载器加载的 Class 实例;
  4. 调用本类加载器的 findClass(...) 方法,试图获取对应的字节码,如果获取的到,则调用 defineClass(...) 导入类型到方法区;如果获取不到对应的字节码或者其他原因导致失败,返回异常给 loadClass(...) , loadClass(....) 转抛异常,终止加载过程
  5. 注意:被两个加载器加载的同一个类,JVM 不认为是相同的类
  6. 文件系统类加载器代码:
package com.coderbean.test;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * 自定义文件系统类加载器
 * @author chang
 *
 */
public class FileSystemClassLoader extends ClassLoader {
   private String rootDir;
   public FileSystemClassLoader(String rootDir){
       this.rootDir = rootDir;
   }

   @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
    Class<?> c = findLoadedClass(name);
    //首先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类
    if(null != c){
        return c; 
    }else{
        ClassLoader parent = this.getParent();
        try {
        c = parent.loadClass(name); //委派给父类加载器加载指定类
        } catch (Exception e) {
        // TODO Auto-generated catch block
        //e.printStackTrace();
        }
        if(null != c){
        return c;
        }else{
        byte[] classData = getClassData(name);
        if(null == classData){
            throw new ClassNotFoundException();
        }else{
//          System.out.println(classData.length);
            c = defineClass(name, classData, 0, classData.length);
        }
        }
    }
    return c;
    }
   private byte[] getClassData(String classname){
       String path = this.rootDir + "/" + classname.replace('.', '/') + ".class";
//       System.out.println(path);
       InputStream is = null;
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       try {
       is = new FileInputStream(path);

       byte[] buffer = new byte[1024];
       int temp = 0;
       while(-1!=(temp = is.read(buffer))){
           baos.write(buffer, 0, temp);
       }

       return baos.toByteArray();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }finally{
            if(null != is){
            try {
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            }
            if(baos != null)
            {
            try {
            baos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            }
        }

   }
}

线程上下文加载器

双亲委托机制以及类加载器的问题

  • 一般情况下,保证同一个类中所关联的其他类都是由当前类的类加载器加载的。比如ClassA本身在Ext下找到,那么他里面 new 出来的一些类也只能 Ext 去查找了(不会低一个级别),所以有些明明 App 可以找到的,却找不到了
  • JDBC API 他有实现的 driven 部分(sqlserver / mySql),我们的JDBC API 都是由Boot 或者 Ext 来载入的, 但是 JDBC driven 却是由 Ext 和 App 来载入的,那么就有可能找不到 driven 了。 在 Java领域中,其实只要分成这种API + SPI(Service Provided Interface,特定厂商提供)的,都会遇到这种问题。
  • 常见的SPI有JDBC、JCE、JNDI、JAXP、和 JBI 等。这些 SPI 的接口由JAVA核心库提供, 如 JAXP 的 SPI 接口定义包含在javax.xml.parsers 包中。SPI接口是JAVA核心库的一部分,是由引导类加载器来加载的;SPI 实现的 Java 类一般是由系统类加载器来加载的。引导类加载器无法找到 SPI 的实现类,因为它只加载 Java 的核心库。
  • 通常你需要动态加载资源的时候,你至少有三个 ClassLoader 可以选择:
    1. 系统类加载器(或者叫 应用类加载器)System ClassLoader 或 Application ClassLoader
    2. 当前类加载器
    3. 当前线程类加载器
  • 线程类加载器是为了抛弃双亲委派加载链模式。
    • 每一个线程都有一个关联的线程上下文类加载器。如果你使用new Thread() 方式生成新的线程,新线程将继承其父线程的上下文类加载器。如果程序对于线程上下文类加载器没有任何改动的话,程序中所有的线程都将使用系统类加载器作为上下文类加载器
    • Thread.currentThread().getContextClassLoader()
    • Thread.currentThread().setContextClassLoader()
  • 线程上下文类加载器测试代码:
package com.coderbean.test;
/**
 * 线程上下文类加载器测试
 * @author chang
 *
 */
public class Demo05 {
    public static void main(String[] args) throws ClassNotFoundException {
    ClassLoader loader = Demo05.class.getClassLoader();
    System.out.println(loader);

    ClassLoader loader2 = Thread.currentThread().getContextClassLoader();
    System.out.println(loader2);

    Thread.currentThread().setContextClassLoader(new FileSystemClassLoader("/home/chang/Documents/test"));
    System.out.println(Thread.currentThread().getContextClassLoader());

    Class<?> c  = Thread.currentThread().getContextClassLoader().loadClass("HelloWorld");
    System.out.println(c);
    System.out.println(c.getClassLoader());
    }
}

服务器加载原理和OSGI介绍

TOMCAT 服务器的类加载机制

  • 一切为了安全
    • TOMCAT 不能使用系统默认的类加载器。
      • 如果TOMCAT跑你的Web项目使用系统的类加载器是十分危险的,你可以直接肆无忌惮的操作系统的各个目录
      • 对于运行在 Java EE 容器中的Web应用来说,类加载器的实现方式与一般的 Java 应用不同。
      • 每个 Web 应用都有一个对应的类加载器的实例。该类加载也使用代理模式(不同于双亲委派机制),不同的是他首先尝试去加载某个类,如果找不到再代理给父类加载器,这与一般类加载器的顺序是相反的。但也是为了保证安全,这样核心库就不在查询范围之内。
  • 为了安全 TOMCAT 需要自己实现类加载器
    • 我可以限制你只把类写在指定的地方,否则不给你加载!

OSGi 原理介绍

  • OSGI (Open Service Gateway Initative) 是面向Java的动态模块系统。它为开发人员提供了面向服务和基于组件的运行环境,并提供标准的方式用来管理软件的生命周期
  • OSGi 已经被实现和部署在很多产品上,在开源社区也得到了广泛的支持。Eclipse 就是基于 OSGi 技术来构建的。
  • 原理:
    • OSGi 中的每个模块(bundle)都包含 Java 包和类。模块可以声明他所以来的需要导入(import)的其他模块的 Java 包和类(通过 Import-Package),也可以声明导出(export)自己的包和类,供其他模块使用(通过 Export-Package)。也就是说需要能够隐藏和共享一个模块中的某些 Java 包和类。这是通过 OSGi 特有的类加载器机制来实现的。 OSGi 中的每个模块都有对应的一个类加载器。它负责加载模块自己包含的 Java 包和类。 当它需要加载 Java 核心库的类时(以 java 开头的包和类),它会代理给父类加载器(通常是启动类加载器)来完成。当它需要加载所导入的Java类时,它会代理给导出此 Java 类的模块来完成加载。模块也可以显式的声明某些 Java 包和类,必须由父类加载器加载。只需要设置系统属性 org.osgi.framework.bootdelegation 的值即可`
故障转移集群无法连接到节点_Windows 2012系统群集故障转移集群 理论知识很重要!集群和群集是什么意思?其实看到标题可能会感觉有点绕,简单易懂的来说一下:集群,英文名称为Cluster,集群的意思就是将多个系统连接在一起,可以让多台服务器能够像一台服务器那样工作。通常采用集群系统是为了提高系统的稳定性和网络中心的数据处理能力以及服务能力。第二个就是:群集,其实这个概念也不难理解,群集是把多个计算机连接在一起,形成整形,随后可以更好的利用设备资源的一项新... 阅读详情

相关推荐

介绍七种常见还危险的病毒(带样本)

简介:能够感染用户计算机bai系统中的.exe、.dll和.html文件,将自身加密以后缀加到目标文件中。样本(源文件):https://wwx.lanzoux.com/iJx4njrpz1c / https://wwx.lanzoui.com/iYRNLwd8ldc。英文名称:Virus.Win32.Viking.A(标准) / Worm.Win32.Fujack.A(标准)英文名称:Net-Worm.Win32.Blaster.A(标准)/ Lovesan.A/ Msblast.A。

2301_78858007的博客 8381

Java_类加载器

对Java类加载器的讲解分析,包含程序段

AI+全栈,AI+应用,实操落地,前沿技术 2258

IsaacLab从入门到精通(二) 导入自定义机器人

IsaacLab系列第二讲,导入自定义的机器人及设置

DejaWu33的博客 8463

Java的类加载器有哪些

职责:满足特定需求的类加载器,通常在应用程序中自定义实现。实现:继承java.lang.ClassLoader并重写findClass方法。加载路径:由开发者自行定义,可以是文件系统、网络、数据库等。父类加载器:可以指定,也可以继承应用程序类加载器。@Overridetry {// 将类名转换为文件路径// 读取类文件的字节码// 将字节码转换为 Class 对象当内置的三大类加载器无法满足需求时,就需要自定义类加载器。目的加载非 ClassPath 路径的类。

埃泽漫笔 1092

AI大模型API中转站选型指南:12项关键指标与实战评估

随着AI大模型技术的快速迭代,企业面临着一个核心挑战:如何在基础模型频繁更新的背景下,为业务系统选择稳定可靠的API中转服务?本文基于真实生产环境测试数据,从12个关键维度系统评估主流API中转站平台,帮助技术团队在模型快速演进的生态中做出科学选型决策。 1. API中转站的核心价值与业务场景 1.1 什么是API中转站 API中转站(API Gateway/Aggregator)是连接业务系统与多个大模型厂商的中间层服务。它通过统一的接口封装了不同厂商的API协议差异,为企业提供标准化的模型调用能力。在实

weixin_29056101的博客 442

RAG项目简历包装指南:从“流水线工人”到“问题解决者”的跃迁(附代码与思路)

本文代码已在Python 3.11 + CUDA 12.3环境测试,部分功能需LangChain 0.2+支持。

Conan_0728的博客 1885

【Java 基础篇】Java类加载器详解

Java允许开发人员自定义类加载器,以满足特定的加载需求。自定义类加载器必须继承类,并重写findClass方法。在findClass方法中,开发人员可以根据自己的规则和逻辑来加载类的字节码。// 根据名称加载类的字节码 byte [ ] byteCode = loadClassByteCode(name);// 调用defineClass方法将字节码转换为Class对象 return defineClass(name , byteCode , 0 , byteCode . length);

繁依Fanyi的博客 1万+

Tesseract-Ocr踩坑下载以及进行检验

1 OCR,即Optical Character Recognition:光学字符识别,是指通过扫描字符,然后通过其形状将其翻译成电子文本的过程。下载完成后进行解压找到这两个,然后复制到之前下载Tesseract-Ocr的tessdata文件下。可能会出现报错说chi下载的问题咱们不用管继续ok让它先下载完毕,后续会有下载chi的步骤。四、检验tesseract使用(将以下图片进行下载我这里将以下图片命名为3.png)我这里选的是2024年的版本如果下载不了;4 在安装的时候(找到下载的exe文件,双击)

m0_51428325的博客 1915

Java中有哪些类加载器

在 Java 中,类加载器(ClassLoader)负责将类的字节码加载到 JVM 中,并生成对应的。

完全体 868

8.2 发展趋

分子泵技术正处在一个快速变革的时代,面对日益增长的应用需求和不断涌现的技术挑战,其发展呈现出多元化、智能化和高度集成化的趋势。这些发展趋势不仅代表着技术创新的方向,也预示着分子泵在未来工业体系中将要扮演的更加重要的角色。

技术工作者 113

PCL 从LAS文件中获取点云的颜色【2026最新版】

PCL从LAS文件中获取点云的RGB信息(pcl::PointXYZRGB)并进行可视化。博客长期更新,本文最新更新时间为:2026年5月4日。

点云侠的博客 1719

Java 类加载器

类加载器可以说是Java语言的一项创新,让应用程序自己决定如何去获取所需的类的二进制字节流。

Happy博客 1065

【Windows Server 2019】组策略的配置与管理——理论基础

博文介绍了组策略的定义,作用和分类。组策略包括计算机配置和用户配置;组策略又分为为基于本地的组策略和基于AD(活动目录)的域组策略。并说明了不同组策略发生冲突时默认的规则。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 1万+

java 类加载器

类加载器基本概念 什么是类加载器 顾名思义,类加载器(class loader)用来加载 Java 类到Java 虚拟机中。 具体的说就是:Java源程序(.java 文件)在经过Java 编译器编译之后就被转换成 Java 字节代码(.class文件)。类加载器负责读取 Java字节代码,并转换成 java.lang.Class类的一个实例。 系统提供的类加载器 系统提供的类加

卖克的专栏 4万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java中默认的类加载器

java中的类加载器类型以及工作原理。     java中默认的有三种类型加载器。分别是:系统类加载器(应用类加载器)、扩展类加载器、引导类加载器。     上篇博客的例子已经测试了加载器类型是: sun.misc.Launcher$AppClassLoader@f4f44a,这个是系统类加载器。来看一下父类的加载器类型: //测试类加载器 System.out.println("f

2712

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Java 类加载器解析

类加载器是 Java 虚拟机(JVM)的重要组成部分,其核心职责是根据类的全限定名(如com.example.User)找到对应的.class字节码文件,并将其加载到 JVM 的方法区(Method Area),最终在堆内存中生成一个代表该类的java.lang.Class对象。加载加密的 .class 文件从非标准位置(如网络、数据库)加载类实现热部署(Hot Deployment)实现模块化隔离实现类版本控制继承 ClassLoader 类通常重写 findClass() 方法。

Toroto5的博客 1043

【Java】类加载器

当一个类被使用的时候,才会加载到内存类加载的过程: 加载、验证、准备、解析、初始化这个需要回忆一下我们刚刚学习的三种类加载器。其中用的最多的就是系统类加载器,如果有必要,我们还可以加入自定义类加载器类加载器的双亲委派模型,在这个模型中,除了顶层的启动类加载器之外,其他的加载器都应该有自己的父类加载器。例如自定义类加载器的父类就是系统类加载器系统类加载器的父类就是平台类加载器平台类加载器的父类就是启动类加载器,由于启动类加载器是最顶层的,所以它上面就没有父类加载器了。

qq_39921135的博客 1067

java 类加载器原理_Java类加载器的工作原理

Java类加载器的作用就是在运行时加载类。Java类加载器基于三个机制:委托、可见性和单一性。委托机制是指将加载一个类的请求交给父类加载器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它。可见性的原理是子类的加载器可以看见所有的父类加载器加载的类,而父类加载器看不到子类加载器加载的类。单一性原理是指仅加载一个类一次,这是由委托机制确保子类加载器不会再次加载父类加载器加载过的类。正确理解类...

weixin_39765325的博客 110

java类加载器是什么?

类加载器是有了解吗? 解析:底层原理的考察,其中涉及到类加载器的概念,功能以及一些底层的实现。 答:顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。 类加载器负责读取 Java ...

南 墙 1万+

java类加载器

类加载是一个双亲委派的过程,当类加载器加载一个类的时候,首先会将这个请求委托给父类去完成,每一个层次类加载器都是如此,当父类加载器无法加载的时候,子类加载器才会尝试自己去加载。:Java中的类加载器可以创建不同的类加载器实例,每个实例都有自己的命名空间。:Java类加载器可以实现对加载类的安全性和权限控制,例如可以通过自定义类加载器来限制某些类只能在特定的安全环境中加载。:开发者可以根据需要继承java.lang.ClassLoader类,实现自定义的类加载器,用于特定的加载需求。

lqq1667821818的博客 2125

java基础类加载器_JAVA基础_类加载器

什么是类加载器类加载器是Java语言在1.0版本就引入的。最初是为了满足JavaApplet需要。现在类加载器在Web容器和OSGI中得到了广泛的应用,一般来说,Java应用的开发人员不需要直接同类加载器进行交互。Java虚拟机默认的行为就已经足够满足大多数情况的需求了。不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时候在ClassNotFound...

weixin_33978578的博客 82

java类加载器有哪些

用户自定义类加载器(User-Defined ClassLoader),ClassLoader子类。用户自定义类加载器实现:开发人员通过继承抽象类java.lang.ClassLoader类的方式,实现自己的类加载器,以满足一些特殊需求。不建议覆盖loadClass()方法,而是建议把自定义的类加载逻辑写在findCalss()方法中。

booker009的博客 674

Java类加载器及Android类加载器基础

引子Android插件化与热更新技术日渐成熟,当你研究这些技术时会发现类加载器在其中占据重要地位。Java语言天生就有灵活性、动态性,支持运行期间动态组装程序,而这一切的基础就是类加载器。Java中的类加载器Java灵活性和动态性的原因Java源代码被编译器编译成字节码,即从.java文件编译为.class文件,而.class文件就是通过类加载器加载到虚拟机内存中的。虚拟机的类加载(Class Lo

Battling against our own ignorance 3035

java类加载器说法正确的_Java中的类加载器

Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由Java 应用开发人员编写的。A 系统提供的类加载器主要有下面三个:引导类加载器(bootstap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承java.lang.ClassLoader。主要负责jdk_home/lib目录下的核心api 或 -Xbootclasspath选项制定...

weixin_33595935的博客 1523

Java中的类加载器

名称加载哪的类说明无法直接访问上级为 Bootstrap,显示为 nullclasspath上级为 Extension自定义类加载器自定义上级为 App启动类加载器(bootstrap class loader):由 C++ 实现的,没有对应的 Java 对象,因此在 Java 中只能用 null 来指代。负责加载最为基础、最为重要的类,比如存放在 JRE 的 lib 目录下 jar 包中的类(以及由虚拟机参数 -Xbootclasspath 指定的类)扩展类加载器。

hongcaixia的博客 1271

java 类加载器_Java 类加载器

一、概述类加载器通过一个类的全限定名来获取描述此类的二进制字节流。类加载器在类层次划分、OSGi、热部署、代码加密等领域发挥着重要的作用。比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提之下才有意义,否则,即使这两个类是来源于同一个 Class 文件,只要加载它们的类加载器不同,那这两个类就必定不相等。这里的“相等”包括 equal() 方法、isAssignableForm()...

weixin_32791013的博客 410

Java类加载器 ClassLoader的解析

Java类加载器 ClassLoader的解析

xinyuan的专栏 3736
上一篇: JVM核心之 JVM运行和类加载全过程
下一篇: Java 内部类
coderbean
博客等级 码龄11年 12粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值