Class.getResource用法

本文详细介绍了在Java中如何使用`Class.getResource()`和`Class.getResourceAsStream()`方法获取文件资源,强调了避免硬编码路径的重要性。通过实例展示了如何在不同目录结构下获取`file1.txt`到`file4.txt`的路径,讲解了`getResource()`方法参数的相对路径和绝对路径概念,并对比了使用类加载器和`request.getRealPath()`的区别。总结了在类路径和Web应用环境下正确获取资源文件的方法。

本文涉及的方法:

this.getClass().getResource(*) 

this.getClass().getClassLoader().getResource(*)

request.getRealPath(*)=request.getSession().getServletContext().getRealPath

getServletPath()

getContextPath()

getRequestURI()

getRequestURL()

用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得 c:/test.txt文件,就会这样用File file = new File("c:/test.txt");这样用有什么问题,相信大家都知道,就是路径硬编码,对于JAVA精神来说,应用应该一次成型,到处可用,并且从现实应用来讲,最终生成的应用也会部署到Windows外的操作系统中,对于linux来说,在应用中用了c:/这样的字样,就是失败,所以,我们应该尽量避免使用硬编码,即直接使用绝对路径。

  在Servlet应用中,有一个getRealPath(String str)的方法,这个方法尽管也可以动态地获得文件的路径,不秘直接手写绝对路径,但这也是一个不被建议使用的方法,那么,我们有什么方法可以更好地获得文件呢?

      那就是Class.getResource()与Class.getResourceAsStream()方法,但很多人还是不太懂它的用法,因为很多人(比如不久前的我)都不知道应该传怎么样的参数给它,当然,有些人己经用得如火纯青,这些人是不需要照顾的,在此仅给不会或者还不是很熟的人解释一点点。

比如我们有以下目录

|--project

    |--src

        |--javaapplication

            |--Test.java

            |--file1.txt

        |--file2.txt

    |--build 

        |--javaapplication

            |--Test.class

            |--file3.txt

        |--file4.txt

在上面的目录中,有一个src目录,这是JAVA源文件的目录,有一个build目录,这是JAVA编译后文件(.class文件等)的存放目录

那么,我们在Test类中应该如何分别获得

file1.txt  file2.txt  file3.txt  file4.txt这四个文件呢?

首先讲file3.txt与file4.txt

file3.txt:

Java代码 复制代码
  1. 方法一:File file3 = new File(Test.class.getResource("file3.txt").getFile());   
  2.   
  3. 方法二:File file3 = new File(Test.class.getResource("/javaapplication/file3.txt").getFile());   
  4.   
  5. 方法三:File file3 = new File(Test.class.getClassLoader().getResource("javaapplication/file3.txt").getFile());  

  

file4.txt:

Java代码 复制代码
  1. 方法一:File file4 = new File(Test.class.getResource("/file4.txt").getFile());   
  2.   
  3. 方法二:File file4 = new File(Test.class.getClassLoader().getResource("file4.txt").getFile());  

  

很好,我们可以有多种方法选择,但是file1与file2文件呢?如何获得?

答案是,你只能写上它们的绝对路径,不能像file3与file4一样用class.getResource()这种方法获得,它们的获取方法如下

假如整个project目录放在c:/下,那么file1与file2的获取方法分别为

file1.txt

Java代码 复制代码
  1. 方法一:File file1 = new File("c:/project/src/javaapplication/file1.txt");   
  2.   
  3. 方法二:。。。没有  

file2.txt

Java代码 复制代码
  1. 方法一:File file2 = new File("c:/project/src/file2.txt");   
  2.   
  3. 方法二:。。。也没有  

总结一下,就是你想获得文件,你得从最终生成的.class文件为着手点,不要以.java文件的路径为出发点,因为真正使用的就是.class,不会拿个.java文件就使用,因为java是编译型语言嘛

至于getResouce()方法的参数,你以class为出发点,再结合相对路径的概念,就可以准确地定位资源文件了,至于它的根目录嘛,你用不同的IDE build出来是不同的位置下的,不过都是以顶层package作为根目录,比如在Web应用中,有一个WEB-INF的目录,WEB-INF目录里面除了web.xml文件外,还有一个classes目录,没错了,它就是你这个WEB应用的package的顶层目录,也是所有.class的根目录 “/”,假如clasaes目录下面有一个file.txt文件,它的相对路径就是"/file.txt",如果相对路径不是以"/"开头,那么它就是相对于.class的路径。。

还有一个getResourceAsStream()方法,参数是与getResouce()方法是一样的,它相当于你用getResource()取得File文件后,再new InputStream(file)一样的结果

来源:http://gavin-chen.javaeye.com/blog/261151

public URL getResource(String name)  查找带有给定名称的资源,查找给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)

在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:

  • 如果 name 以 '/'  开始,则绝对资源名是 '/' 后面的 name 的一部分。
  • 否则,绝对名具有以下形式:
    modified_package_name/name

    其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。

Java代码 复制代码
  1. Class.getResource(""); 获取classpath   
  2.   
  3.     
  4.   
  5. Class.getResource("JMF.class"); 代表获取相于类路径当前包下的SendService.class的类路径.   
  6.   
  7. /D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class-------->打印出的结果   
  8.   
  9. Class.getResource("/jmf/WebCamSwing.class"); /jmf/WebCamSwing.class->代表相于类路径的绝对路径   
  10.   
  11. file:/D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class  -------->打印出的结果  

我们怎么获得Object的类路径:

Class.getResource("/java/lang/Object.class") 因为Object是通过引导类加载器 (BootStrapClassLoader)加载的,所以此方法通过系统类加载器来查找资料, 所以我们要指定类的绝对路径/java /lang/Object.class

Java代码 复制代码
  1. public java.net.URL getResource(String name) {   
  2.         name = resolveName(name);   
  3.         ClassLoader cl = getClassLoader0();   
  4.         if (cl==null) {   
  5.             // A system class.   
  6.             return ClassLoader.getSystemResource(name);   
  7.         }   
  8.         return cl.getResource(name);   
  9.     }  

我们来看看如何通过系统类加载器来查找Object:

Java代码 复制代码
  1. Class.getClassLoader().getSystemResource("java/lang/Object.class")  

打印出来的结果多是:

jar:file:/E:/Program/Java/jdk1.5.0_15/jre/lib/rt.jar!/java/lang/Object.class

为什么getResource("")前面要加"/",而getSystemResource("")前面不用加呢?

Java代码 复制代码
  1. private String resolveName(String name) {   
  2.         if (name == null) {   
  3.             return name;   
  4.         }   
  5.         if (!name.startsWith("/")) {   
  6.             Class c = this;   
  7.             while (c.isArray()) {   
  8.                 c = c.getComponentType();   
  9.             }   
  10.             String baseName = c.getName();   
  11.             int index = baseName.lastIndexOf('.');   
  12.             if (index != -1) {   
  13.                 name = baseName.substring(0, index).replace('.''/')   
  14.                     +"/"+name;   
  15.             }   
  16.         } else {   
  17.             name = name.substring(1);   
  18.         }   
  19.         return name;   
  20.     }  

  

其实最后还是要把"/"去掉的...

来源http://wangxuliangboy.javaeye.com/blog/345367

下面是我测试的结果:

 

上面为目录结构,下面的方法是在类org.fileupload.servlet.SecondUploadServlet中测试的

Java代码 复制代码
  1. System.out.println("this.getClass().getResource(*)--------------------------------");   
  2.   System.out.println(this.getClass().getResource("")); // .../classes/org/fileupload/servlet/   
  3.   System.out.println(this.getClass().getResource("/")); // .../classes/   
  4.      
  5.   // 编译成class文件, 所以用.java是错的, 应用java   
  6.   System.out.println(this.getClass().getResource("./FirstUploadServlet.java")); // null   
  7.   System.out.println(this.getClass().getResource("/FirstUploadServlet.java")); // null   
  8.   System.out.println(this.getClass().getResource("FirstUploadServlet.java")); // null   
  9.   System.out.println(this.getClass().getResource("SecondUploadServlet.java")); // null   
  10.   System.out.println(this.getClass().getResource("org.fileupload.servlet")); // null   
  11.   System.out.println(this.getClass().getResource("org.fileupload.servlet.SecondUploadServlet.java")); // null   
  12.      
  13.   // ./或最前面没有.和/表示当前目录, /表示类路径根目录, 即classes目录   
  14.   System.out.println(this.getClass().getResource("./FirstUploadServlet.class")); // .../classes/org/fileupload/servlet/./FirstUploadServlet.class   
  15.   System.out.println(this.getClass().getResource("/FirstUploadServlet.class")); // null   
  16.   System.out.println(this.getClass().getResource("FirstUploadServlet.class")); // .../classes/org/fileupload/servlet/FirstUploadServlet.class   
  17.   System.out.println(this.getClass().getResource("SecondUploadServlet.class")); // .../classes/org/fileupload/servlet/SecondUploadServlet.class   
  18.   System.out.println(this.getClass().getResource("/org/fileupload/servlet")); // .../classes/org/fileupload/servlet/   
  19.   System.out.println(this.getClass().getResource("org.fileupload.servlet.SecondUploadServlet.class")); // null   
  20.      
  21.   System.out.println(this.getClass().getResource("test")); // .../classes/org/fileupload/servlet/test/   
  22.   System.out.println(this.getClass().getResource("./test")); // .../classes/org/fileupload/servlet/./test/   
  23.      
  24.   System.out.println(this.getClass().getResource("test/OK.java")); // null   
  25.   System.out.println(this.getClass().getResource("/test/OK.java")); // null   
  26.   System.out.println(this.getClass().getResource("./test/OK.java")); // null   
  27.   
  28.   System.out.println(this.getClass().getResource("test/OK.class")); // .../classes/org/fileupload/servlet/test/OK.class   
  29.   System.out.println(this.getClass().getResource("/test/OK.class")); // null   
  30.   System.out.println(this.getClass().getResource("./test/OK.class")); // .../classes/org/fileupload/servlet/./test/OK.class   
  31.      
  32.   System.out.println(this.getClass().getResource("/classpath.jsp")); // .../classes/classpath.jsp   
  33.      
  34.   System.out.println(this.getClass().getResource("./classpath.jsp")); // null   
  35.   System.out.println(this.getClass().getResource("classpath.jsp")); // null   
  36.      
  37.   System.out.println("\n利用类加载器:");   
  38.   System.out.println("this.getClass().getClassLoader().getResource(*)-------------");   
  39.   System.out.println(this.getClass().getClassLoader().getResource("classpath.jsp"));   
  40.   System.out.println(this.getClass().getClassLoader().getResource("FirstUploadServlet.class")); // null   
  41.   System.out.println(this.getClass().getClassLoader().getResource("org/fileupload/servlet/FirstUploadServlet.class"));   
  42.   System.out.println(this.getClass().getClassLoader().getResource("/org/fileupload/servlet/FirstUploadServlet.class"));   
  43.   System.out.println(this.getClass().getClassLoader().getResource("./org/fileupload/servlet/FirstUploadServlet.class"));   
  44.      
  45.   System.out.println("\nrequest.getRealPath(*)--------------------------------------");   
  46.   // 最前面有没有加左斜杆结果基本是一样的, 只是获取根目录时多或少了一右斜杆而已   
  47.   // 如果最前面为./, 那么结果会变成\.\这样的路径   
  48.   System.out.println(request.getRealPath("")); // ...\commons-fileupload   
  49.   System.out.println(request.getRealPath("/")); // ...\commons-fileupload\   
  50.   System.out.println(request.getRealPath("index.jsp")); // ...\commons-fileupload\index.jsp   
  51.   System.out.println(request.getRealPath("./index.jsp")); // ...\commons-fileupload\.\index.jsp   
  52.   System.out.println(request.getRealPath("/index.jsp")); // ...\commons-fileupload\index.jsp   
  53.   System.out.println(request.getRealPath("fileupload/firstupload.jsp")); // ...\commons-fileupload\fileupload\firstupload.jsp   
  54.   System.out.println(request.getRealPath("/fileupload/firstupload.jsp")); // ...\commons-fileupload\fileupload\firstupload.jsp   
  55.   System.out.println(request.getRealPath("./fileupload/firstupload.jsp")); // ...\commons-fileupload\.\fileupload\firstupload.jsp  
  56.   System.out.println(request.getRealPath("./fileupload")); // ...\commons-fileupload\.\fileupload   
  57.   System.out.println(request.getRealPath("/fileupload")); // ...\commons-fileupload\fileupload   
  58.   System.out.println(request.getRealPath("fileupload")); // ...\commons-fileupload\fileupload   
  59.      
  60.   // request.getSession().getServletContext().getRealPath与request.getRealPath结果一样   
  61.   System.out.println("\nrequest.getSession().getServletContext().getRealPath(*)------");   
  62. //  System.out.println(request.getSession().getServletContext().getRealPath("/")); // ...\commons-fileupload\   
  63.   System.out.println(request.getSession().getServletContext().getRealPath("")); // ...\commons-fileupload   
  64.   System.out.println(request.getSession().getServletContext().getRealPath("/")); // ...\commons-fileupload\   
  65.   System.out.println(request.getSession().getServletContext().getRealPath("index.jsp")); // ...\commons-fileupload\index.jsp  
  66.   System.out.println(request.getSession().getServletContext().getRealPath("./index.jsp")); // ...\commons-fileupload\.\index.jsp   
  67.   System.out.println(request.getSession().getServletContext().getRealPath("/index.jsp")); // ...\commons-fileupload\index.jsp   
  68.   System.out.println(request.getSession().getServletContext().getRealPath("fileupload/firstupload.jsp")); // ...\commons-fileupload\fileupload\firstupload.jsp   
  69.   System.out.println(request.getSession().getServletContext().getRealPath("/fileupload/firstupload.jsp")); // ...\commons-fileupload\fileupload\firstupload.jsp   
  70.   System.out.println(request.getSession().getServletContext().getRealPath("./fileupload/firstupload.jsp")); // ...\commons-fileupload\.\fileupload\firstupload.jsp   
  71.   System.out.println(request.getSession().getServletContext().getRealPath("./fileupload")); // ...\commons-fileupload\.\fileupload   
  72.   System.out.println(request.getSession().getServletContext().getRealPath("/fileupload")); // ...\commons-fileupload\fileupload   
  73.   System.out.println(request.getSession().getServletContext().getRealPath("fileupload")); // ...\commons-fileupload\fileupload   
  74.      
  75.   System.out.println("\nothers-------------------------------------------------------");   
  76.   System.out.println(request.getServletPath()); // /servlet/SecondUploadServlet   
  77.   System.out.println(request.getContextPath()); // /commons-fileupload   
  78.   System.out.println(request.getRequestURI()); // /commons-fileupload/servlet/SecondUploadServlet   
  79.   System.out.println(request.getRequestURL()); // http://localhost:8080/commons-fileupload/servlet/SecondUploadServlet
<think> 我们正在讨论如何在Java中读取JAR包内的资源文件,特别是使用`Class.getResource()`和`ClassLoader.getResource()`方法。用户之前的问题是关于路径对应,现在想深入了解这两个方法的用法、区别以及在处理JAR包文件路径时的应用。 首先,我们需要明确这两个方法的核心机制: 1. **`Class.getResource()`**: - 有两种路径写法:以`/`开头和不以`/`开头。 - 以`/`开头:表示从类路径的根目录开始查找(绝对路径)。 - 不以`/`开头:表示相对于当前类所在的包路径(相对路径)。 - 内部实现会委托给`ClassLoader`,但会对路径进行处理。 2. **`ClassLoader.getResource()`**: - 只有一种路径写法:必须以非`/`开头,因为`ClassLoader`的路径总是从类路径的根目录开始(绝对路径)。 - 不能使用相对路径(即相对于当前类的路径),因为它没有当前类的上下文。 在读取JAR包中的文件时,路径都是相对于类路径根目录的,使用正斜杠`/`分隔,并且大小写敏感。 下面我们结合具体示例来说明: ### 1. 路径基准点差异 假设我们有如下JAR结构: ``` myapp.jar ├── com/ │ └── example/ │ └── App.class └── config/ └── app.properties ``` #### 使用`Class.getResource()`: - 从`App.class`中读取`app.properties`: ```java // 绝对路径(从根目录开始) URL url1 = App.class.getResource("/config/app.properties"); // 相对路径(相对于com/example) // 错误示例:因为相对路径会查找com/example/config/app.properties,但实际不存在 URL url2 = App.class.getResource("config/app.properties"); // 返回null ``` #### 使用`ClassLoader.getResource()`: ```java // 正确:从根目录开始,不需要前导/ URL url = App.class.getClassLoader().getResource("config/app.properties"); // 错误:不能以/开头 URL errorUrl = App.class.getClassLoader().getResource("/config/app.properties"); // 返回null ``` ### 2. 方法选择建议 - **优先使用`ClassLoader.getResource()`**:因为其路径行为一致(总是从根目录开始),避免相对路径带来的混淆。 - 在需要相对当前类的路径时,才使用`Class.getResource()`(相对路径),但这种情况较少。 ### 3. JAR包读取的通用原则 无论使用哪种方法,都要注意: - **路径格式**:使用`/`分隔,无盘符和协议头。 - **资源存在性**:打包后资源是否在正确位置(可通过`jar tf myapp.jar`验证)。 ### 4. 常见问题排查 若返回`null`,检查: 1. 路径是否拼写正确(大小写、多余/缺少目录) 2. 资源是否真的打包到JAR中 3. 是否错误使用了绝对路径(在`ClassLoader`中以`/`开头) ### 5. 代码示例对比 ```java public class ResourceDemo { public static void main(String[] args) { // 使用ClassLoader(推荐) InputStream is1 = ResourceDemo.class.getClassLoader() .getResourceAsStream("config.properties"); // 使用Class的绝对路径 InputStream is2 = ResourceDemo.class .getResourceAsStream("/config.properties"); // 使用Class的相对路径(不推荐,易出错) InputStream is3 = ResourceDemo.class .getResourceAsStream("../../config.properties"); // 脆弱路径 } } ``` ### 总结表:关键区别 | 特性 | `Class.getResource()` | `ClassLoader.getResource()` | |--------------------------|----------------------------------------|---------------------------------------| | **路径基准** | 可绝对(/开头)或相对(当前类所在包) | 总是类路径根目录(不能以/开头) | | **委托机制** | 内部调用`ClassLoader`但处理路径 | 直接由类加载器实现 | | **JAR内资源读取适用性** | 高(需注意绝对/相对路径) | 高(路径行为一致) | | **空路径处理** | 空字符串返回当前类目录 | 空字符串会导致`NullPointerException` | | **路径规范化** | 自动处理`..`和`.` | 不处理相对路径符号 | > 📌 **黄金法则**: > 在JAR中读取资源时,**优先使用`ClassLoader.getResourceAsStream(String path)`**,并确保`path`是**从类路径根目录开始的相对路径**(如`"dir/file.txt"`)。 ### 相关问题 1. 为什么`getResource`返回的URL格式是`jar:file:/path.jar!/resource`? 2. 如何解决多模块项目中的资源文件冲突? 3. 在OSGi环境中读取资源文件有什么不同? 4. 如何通过`ResourceBundle`读取JAR内的国际化属性文件? 5. 使用`getResourceAsStream`读取大文件时如何避免内存溢出? 遇到具体路径问题可提供资源位置和代码片段,我会给出针对性修正方案! </think>### `Class.getResource()` 与 `ClassLoader.getResource()` 详解 在读取 JAR 包中资源文件时,这两者的路径处理机制和委托关系是核心差异点。以下是关键对比: --- #### 🧩 一、路径解析机制对比 | **特性** | `Class.getResource(String path)` | `ClassLoader.getResource(String name)` | |-----------------------|----------------------------------------------------------|---------------------------------------------------------| | **路径基准点** | 路径以 `/` 开头:类路径根目录<br>路径不以 `/` 开头:**当前类所在包目录** | **始终从类路径根目录开始**(无论是否以 `/` 开头) | | **路径规范化** | 自动解析相对路径(如 `../`) | 直接按字面路径查找,不解析相对路径 | | **空路径处理** | `getResource("")` 返回当前类所在目录 URL | `getResource("")` 返回 `null` | | **委托机制** | 内部调用 `ClassLoader.getResource()`<br>但会预处理路径 [^2] | 直接由类加载器实现查找 | --- #### 📦 二、JAR 包资源读取场景示例 假设 JAR 结构如下: ```bash myapp.jar ├── com/example/App.class └── config/settings.properties ``` ##### ✅ 正确用法: ```java // 1. 使用 ClassLoader (推荐) InputStream is1 = App.class.getClassLoader() .getResourceAsStream("config/settings.properties"); // ✅ 根目录基准 // 2. 使用 Class (绝对路径) InputStream is2 = App.class .getResourceAsStream("/config/settings.properties"); // ✅ 斜杠开头表示根目录 // 3. 使用 Class (相对路径 - 从当前类目录出发) InputStream is3 = App.class .getResourceAsStream("../../config/settings.properties"); // ✅ 但路径脆弱 ``` ##### ❌ 错误用法: ```java // 错误1: ClassLoader 尝试用绝对路径 InputStream err1 = classLoader.getResourceAsStream("/config/settings.properties"); // ❌ 返回 null // 错误2: Class 未用斜杠的相对路径 InputStream err2 = App.class.getResourceAsStream("config/settings.properties"); // ❌ 实际查找路径: com/example/config/settings.properties ``` --- #### 🔧 三、JAR 环境下的特殊行为 1. **URL 格式差异** - `Class.getResource()` 返回 URL 格式: `jar:file:/app.jar!/com/example/icon.png` - `ClassLoader.getResource()` 返回相同格式 → 两者在 JAR 中本质上调用相同底层方法 [^1] 2. **资源存在性验证** 调试技巧:打印资源 URL ```java URL url = App.class.getResource("/config/settings.properties"); System.out.println(url); // 输出: jar:file:/path/myapp.jar!/config/settings.properties ``` 3. **多 ClassLoader 场景** 在 OSGi 或容器环境中,`ClassLoader.getResource()` 可能仅访问当前模块的资源,而 `Class.getResource()` 会使用加载该类的 ClassLoader,行为更可控。 --- #### ⚠ 四、避坑指南 1. **路径分隔符** 始终用 **正斜杠 `/`**: ```java // 跨平台兼容 getResourceAsStream("data/images/logo.png") // ✅ getResourceAsStream("data\\images\\logo.png") // ❌ Windows 风格失效 ``` 2. **资源更新问题** - JAR 包内资源**不可修改**(只读) - 需动态修改的配置应放在 JAR 外部,用 `FileInputStream` 读取 [^3] 3. **性能对比** `Class.getResource()` 多一次路径预处理,但差异可忽略;优先考虑**代码可读性**。 --- #### 💡 最佳实践总结 1. **优先选择 `ClassLoader.getResourceAsStream()`** 路径行为一致,避免相对路径混淆 2. **绝对路径写法规范** ```java // ClassLoader 风格 (无前导斜杠) classLoader.getResourceAsStream("config/app.conf") // Class 风格 (必须有前导斜杠) MyClass.class.getResourceAsStream("/config/app.conf") ``` 3. **开发期验证** 使用 Maven/Gradle 标准目录结构: ```bash src/main/resources/config/app.conf → JAR 中路径: config/app.conf ``` --- ### 相关问题 1. 为什么 `getResourceAsStream` 有时返回 `null` 但文件确实存在? 2. 如何在 Spring Boot 中优先加载外部配置文件再回退到 JAR 内配置? 3. 多模块项目中如何跨模块访问资源文件? 4. 读取 JAR 中资源文件时出现乱码如何解决? 5. 如何不重启应用动态更新 JAR 内的配置文件? 遇到具体问题可提供代码片段和 JAR 结构,我会给出针对性解决方案
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值