24、Java 编程中的异常、接口与类详解

Java 编程中的异常、接口与类详解

在 Java 编程中,异常处理、接口定义以及各类的使用是非常重要的部分。下面将详细介绍 Java 中多个包下的异常、接口和类,包括它们的定义、作用以及使用场景。

1. java.nio.channels 包中的异常与接口

java.nio.channels 包中,有许多异常和接口用于处理文件锁、通道操作等。

1.1 FileLockInterruptionException

当一个线程在等待文件锁被授予时被另一个线程中断,就会抛出 FileLockInterruptionException 。此时文件通道并未关闭,但捕获该异常后,被中断线程的中断状态会被设置。如果线程不清除其中断状态(通过调用 Thread.interrupted() ),会导致它接触的下一个通道关闭。

public class FileLockInterruptionException 
    extends java.io.IOException 
{ 
    public FileLockInterruptionException() 
}
1.2 GatheringByteChannel 接口

GatheringByteChannel 接口定义了向通道执行聚集写入的方法。

public interface GatheringByteChannel 
    extends WritableByteChannel 
{ 
    public long write (java.nio.ByteBuffer [] srcs) 
        throws java.io.IOException; 
    public long write (java.nio.ByteBuffer [] srcs, int offset, int length) 
        throws java.io.IOException; 
}
1.3 其他异常
  • IllegalBlockingModeException :当尝试执行仅适用于特定阻塞模式的通道操作,而通道当前不在所需模式时抛出。
public class IllegalBlockingModeException 
    extends IllegalStateException 
{ 
    public IllegalBlockingModeException() 
}
  • IllegalSelectorException :当尝试使用不同 SelectorProvider 类的 Selector 注册 SelectableChannel 时抛出。
public class IllegalSelectorException 
    extends IllegalArgumentException 
{ 
    public IllegalSelectorException() 
}
  • NoConnectionPendingException :在非阻塞模式下,对未调用 connect() 开始并发连接过程的 SocketChannel 对象调用 finishConnect() 时抛出。
public class NoConnectionPendingException 
    extends IllegalStateException 
{ 
    public NoConnectionPendingException() 
}
  • NonReadableChannelException :对未以读取权限打开的通道调用 read() 方法时抛出。
public class NonReadableChannelException 
    extends IllegalStateException 
{ 
    public NonReadableChannelException() 
}
  • NonWritableChannelException :对未以写入权限打开的通道调用 write() 方法时抛出。
public class NonWritableChannelException 
    extends IllegalStateException 
{ 
    public NonWritableChannelException() 
}
  • NotYetBoundException :对尚未绑定到端口的 ServerSocketChannel 尝试执行操作(如 accept() )时抛出。
public class NotYetBoundException 
    extends IllegalStateException 
{ 
    public NotYetBoundException() 
}
  • NotYetConnectedException :在调用 connect() 之前或并发连接成功完成之前,尝试使用 SocketChannel 对象进行 I/O 时抛出。
public class NotYetConnectedException 
    extends IllegalStateException 
{ 
    public NotYetConnectedException() 
}
  • OverlappingFileLockException :当尝试获取已被同一 JVM 锁定的文件区域的锁,或另一个线程正在等待锁定同一文件的重叠区域时抛出。
public class OverlappingFileLockException 
    extends IllegalStateException 
{ 
    public OverlappingFileLockException() 
}
1.4 Pipe

Pipe 是一个聚合类,包含一对可选择的通道,它们交叉连接形成回环。 SinkChannel 是管道的写入端,写入其中的任何内容都可以在 SourceChannel 上读取。

public abstract class Pipe 
{ 
    public static Pipe open() 
        throws java.io.IOException 
    public abstract Pipe.SinkChannel sink(); 
    public abstract Pipe.SourceChannel source(); 

    public abstract static class Pipe.SinkChannel 
        extends java.nio.channels.spi.AbstractSelectableChannel 
        implements WritableByteChannel, GatheringByteChannel 
    { 
        public final int validOps() 
    } 

    public abstract static class Pipe.SourceChannel 
        extends java.nio.channels.spi.AbstractSelectableChannel 
        implements ReadableByteChannel, ScatteringByteChannel 
    { 
        public final int validOps() 
    } 
}
1.5 通道接口
  • ReadableByteChannel 接口定义了从通道读取数据到 ByteBuffer 对象的 read() 方法。
public interface ReadableByteChannel 
    extends Channel 
{ 
    public int read (java.nio.ByteBuffer dst) 
        throws java.io.IOException; 
}
  • ScatteringByteChannel 接口定义了从通道执行分散读取的方法。
public interface ScatteringByteChannel 
    extends ReadableByteChannel 
{ 
    public long read (java.nio.ByteBuffer [] dsts) 
        throws java.io.IOException; 
    public long read (java.nio.ByteBuffer [] dsts, int offset, int length) 
        throws java.io.IOException; 
}
  • WritableByteChannel 接口定义了从 ByteBuffer 向通道写入数据的 write() 方法。
public interface WritableByteChannel 
    extends Channel 
{ 
    public int write (java.nio.ByteBuffer src) 
        throws java.io.IOException; 
}
1.6 SelectableChannel

SelectableChannel 是所有能够参与由 Selector 对象控制的选择操作的通道的公共超类。 SelectableChannel 对象可以置于非阻塞模式,并且只能在非阻塞模式下向 Selector 注册。所有继承自 SelectableChannel 的类也实现了 InterruptibleChannel 接口。

public abstract class SelectableChannel 
    extends java.nio.channels.spi.AbstractInterruptibleChannel 
    implements Channel 
{ 
    public abstract Object blockingLock(); 
    public abstract SelectableChannel configureBlocking (boolean block) 
        throws java.io.IOException; 
    public abstract boolean isBlocking(); 
    public abstract boolean isRegistered(); 
    public abstract SelectionKey keyFor (Selector sel); 
    public abstract java.nio.channels.spi.SelectorProvider provider(); 
    public final SelectionKey register (Selector sel, int ops) 
        throws ClosedChannelException 
    public abstract SelectionKey register (Selector sel, int ops, Object att) 
        throws ClosedChannelException; 
    public abstract int validOps(); 
}
1.7 SelectionKey

SelectionKey 封装了 SelectableChannel 对象与 Selector 对象的注册信息。

public abstract class SelectionKey 
{ 
    public static final int OP_ACCEPT 
    public static final int OP_CONNECT 
    public static final int OP_READ 
    public static final int OP_WRITE 

    public final Object attach (Object ob) 
    public final Object attachment() 
    public abstract void cancel(); 
    public abstract SelectableChannel channel(); 
    public abstract int interestOps(); 
    public abstract SelectionKey interestOps (int ops); 
    public final boolean isAcceptable() 
    public final boolean isConnectable() 
    public final boolean isReadable() 
    public abstract boolean isValid(); 
    public final boolean isWritable() 
    public abstract int readyOps(); 
    public abstract Selector selector(); 
}
1.8 Selector

Selector 是一个协调类,用于对注册的 SelectableChannel 对象进行就绪选择,并管理相关的键和状态信息。

public abstract class Selector 
{ 
    public abstract void close() 
        throws java.io.IOException; 
    public abstract boolean isOpen(); 
    public abstract java.util.Set keys(); 
    public static Selector open() 
        throws java.io.IOException 
    public abstract java.nio.channels.spi.SelectorProvider provider(); 
    public abstract int select() 
        throws java.io.IOException; 
    public abstract int select (long timeout) 
        throws java.io.IOException; 
    public abstract int selectNow() 
        throws java.io.IOException; 
    public abstract java.util.Set selectedKeys(); 
    public abstract Selector wakeup(); 
}
1.9 ServerSocketChannel

ServerSocketChannel 类用于监听传入的套接字连接并创建新的 SocketChannel 实例。

public abstract class ServerSocketChannel 
    extends java.nio.channels.spi.AbstractSelectableChannel 
{ 
    public abstract SocketChannel accept() 
        throws java.io.IOException; 
    public static ServerSocketChannel open() 
        throws java.io.IOException 
    public abstract java.net.ServerSocket socket(); 
    public final int validOps() 
}
1.10 SocketChannel

SocketChannel 对象用于在字节缓冲区和网络连接之间传输数据。

public abstract class SocketChannel 
    extends java.nio.channels.spi.AbstractSelectableChannel 
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel 
{ 
    public abstract boolean connect (java.net.SocketAddress remote) 
        throws java.io.IOException; 
    public abstract boolean finishConnect() 
        throws java.io.IOException; 
    public abstract boolean isConnected(); 
    public abstract boolean isConnectionPending(); 
    public static SocketChannel open() 
        throws java.io.IOException 
    public static SocketChannel open (java.net.SocketAddress remote) 
        throws java.io.IOException 
    public abstract int read (java.nio.ByteBuffer dst) 
        throws java.io.IOException; 
    public final long read (java.nio.ByteBuffer [] dsts) 
        throws java.io.IOException 
    public abstract long read (java.nio.ByteBuffer [] dsts, int offset, int length) 
        throws java.io.IOException; 
    public abstract java.net.Socket socket(); 
    public final int validOps() 
    public abstract int write (java.nio.ByteBuffer src) 
        throws java.io.IOException; 
    public final long write (java.nio.ByteBuffer [] srcs) 
        throws java.io.IOException 
    public abstract long write (java.nio.ByteBuffer [] srcs, int offset, int length) 
        throws java.io.IOException; 
}
1.11 其他异常
  • UnresolvedAddressException :当尝试使用无法解析为真实网络地址的 SocketAddress 对象时抛出。
public class UnresolvedAddressException 
    extends IllegalArgumentException 
{ 
    public UnresolvedAddressException() 
}
  • UnsupportedAddressTypeException :当尝试使用表示套接字实现不支持的地址类型的 SocketAddress 对象连接套接字时抛出。
public class UnsupportedAddressTypeException 
    extends IllegalArgumentException 
{ 
    public UnsupportedAddressTypeException() 
}
2. java.nio.channels.spi 包中的类

java.nio.channels.spi 包包含用于创建可插拔、可选择通道实现的类。这些类提供了可被可插拔实现重用的公共方法,但并非所有方法都供公共使用。

2.1 AbstractInterruptibleChannel

AbstractInterruptibleChannel 类为子类提供了实现中断语义的方法。

public abstract class AbstractInterruptibleChannel 
    implements java.nio.channels.Channel, 
java.nio.channels.InterruptibleChannel 
{ 
    protected final void begin() 
    public final void close() 
        throws java.io.IOException 
    protected final void end (boolean completed) 
        throws java.nio.channels.AsynchronousCloseException 
    protected abstract void implCloseChannel() 
        throws java.io.IOException; 
    public final boolean isOpen() 
}
2.2 AbstractSelectableChannel

AbstractSelectableChannel 是所有有资格参与就绪选择的通道实现的超类。

public abstract class AbstractSelectableChannel 
    extends java.nio.channels.SelectableChannel 
{ 
    public final Object blockingLock() 
    public final java.nio.channels.SelectableChannel configureBlocking 
        (boolean block) throws java.io.IOException 
    protected final void implCloseChannel() 
        throws java.io.IOException 
    protected abstract void implCloseSelectableChannel() 
        throws java.io.IOException; 
    protected abstract void implConfigureBlocking (boolean block) 
        throws java.io.IOException; 
    public final boolean isBlocking() 
    public final boolean isRegistered() 
    public final java.nio.channels.SelectionKey keyFor 
        (java.nio.channels.Selector sel) 
    public final SelectorProvider provider() 
    public final java.nio.channels.SelectionKey register 
        (java.nio.channels.Selector sel, int ops, Object att) 
        throws java.nio.channels.ClosedChannelException 
}
2.3 AbstractSelectionKey

AbstractSelectionKey 类为 SelectionKey 实现提供了常用的例程。

public abstract class AbstractSelectionKey 
    extends java.nio.channels.SelectionKey 
{ 
    public final void cancel() 
    public final boolean isValid() 
}
2.4 AbstractSelector

AbstractSelector 类是所有 Selector 实现的超类。

public abstract class AbstractSelector 
    extends java.nio.channels.Selector 
{ 
    protected final void begin() 
    protected final java.util.Set cancelledKeys() 
    public final void close() 
        throws java.io.IOException 
    protected final void deregister (AbstractSelectionKey key) 
    protected final void end() 
    protected abstract void implCloseSelector() 
        throws java.io.IOException; 
    public final boolean isOpen() 
    public final SelectorProvider provider() 
    protected abstract java.nio.channels.SelectionKey register( 
        AbstractSelectableChannel ch, int ops, Object att); 
}
2.5 SelectorProvider

SelectorProvider 类是所有具体通道提供程序类的超类。该类仅由服务提供程序接口机制实例化,不能直接实例化。具体子类的全限定名应列在类加载器类路径中的 META - INF/services/java.nio.channels.spi.SelectorProvider 文件中。

public abstract class SelectorProvider 
{ 
    public abstract java.nio.channels.DatagramChannel 
openDatagramChannel() 
        throws java.io.IOException; 
    public abstract java.nio.channels.Pipe openPipe() 
        throws java.io.IOException; 
    public abstract AbstractSelector openSelector() 
        throws java.io.IOException; 
    public abstract java.nio.channels.ServerSocketChannel 
openServerSocketChannel() 
        throws java.io.IOException; 
    public abstract java.nio.channels.SocketChannel openSocketChannel() 
        throws java.io.IOException; 
    public static SelectorProvider provider() 
}

下面用 mermaid 流程图展示 java.nio.channels 中部分通道操作的流程:

graph TD;
    A[开始] --> B{选择通道类型};
    B --> |SelectableChannel| C[配置阻塞模式];
    C --> D{是否注册到Selector};
    D --> |是| E[等待选择操作];
    E --> F{是否有就绪通道};
    F --> |是| G[处理就绪通道];
    G --> H[继续等待或结束];
    B --> |Pipe| I[打开Pipe];
    I --> J[写入SinkChannel];
    J --> K[从SourceChannel读取];
    K --> H;
    B --> |ServerSocketChannel| L[打开ServerSocketChannel];
    L --> M[绑定端口];
    M --> N[接受连接];
    N --> O[创建SocketChannel];
    O --> P[进行数据传输];
    P --> H;
    B --> |SocketChannel| Q[打开SocketChannel];
    Q --> R[连接远程地址];
    R --> S[进行数据传输];
    S --> H;

通过以上介绍,我们对 java.nio.channels java.nio.channels.spi 包中的异常、接口和类有了更深入的了解。这些异常和类在处理文件锁、通道操作、选择器管理等方面发挥着重要作用,是 Java 编程中不可或缺的一部分。

接下来将继续介绍 java.nio.charset java.util.regex 包中的相关内容。

3. java.nio.charset 包中的类与异常

java.nio.charset 包包含与字符集操作和转码相关的类。

3.1 CharacterCodingException

CharacterCodingException 用于指示遇到字符集编码错误。它是该包中两个特定编码错误异常的父类。低级别编码器和解码器不抛出此异常,而是返回 CoderResult 对象来指示遇到的错误类型。 CharsetEncoder.encode() CharsetDecoder.decode() 便捷方法可能会抛出此异常。

public class CharacterCodingException 
    extends java.io.IOException 
{ 
    public CharacterCodingException() 
}
3.2 Charset

Charset 类封装了一个编码字符集和相关的编码方案。

public abstract class Charset 
    implements Comparable 
{ 
    public final java.util.Set aliases() 
    public static java.util.SortedMap availableCharsets() 
    public boolean canEncode() 
    public final int compareTo (Object ob) 
    public abstract boolean contains (Charset cs); 
    public final java.nio.CharBuffer decode (java.nio.ByteBuffer bb) 
    public String displayName() 
    public String displayName (java.util.Locale locale) 
    public final java.nio.ByteBuffer encode (String str) 
    public final java.nio.ByteBuffer encode (java.nio.CharBuffer cb) 
    public final boolean equals (Object ob) 
    public static Charset forName (String charsetName) 
    public final int hashCode() 
    public final boolean isRegistered() 
    public static boolean isSupported (String charsetName) 
    public final String name() 
    public abstract CharsetDecoder newDecoder(); 
    public abstract CharsetEncoder newEncoder(); 
    public final String toString() 
}
3.3 CharsetDecoder

CharsetDecoder 实例将编码的字节序列转换为字符序列,该类的实例是有状态的。

public abstract class CharsetDecoder 
{ 
    public final float averageCharsPerByte() 
    public final Charset charset() 
    public final java.nio.CharBuffer decode (java.nio.ByteBuffer in) 
        throws CharacterCodingException 
    public final CoderResult decode (java.nio.ByteBuffer in, 
java.nio.CharBuffer out, boolean endOfInput) 
    public Charset detectedCharset() 
    public final CoderResult flush (java.nio.CharBuffer out) 
    public boolean isAutoDetecting() 
    public boolean isCharsetDetected() 
    public CodingErrorAction malformedInputAction() 
    public final float maxCharsPerByte() 
    public final CharsetDecoder onMalformedInput (CodingErrorAction 
newAction) 
    public final CharsetDecoder onUnmappableCharacter (CodingErrorAction 
newAction) 
    public final CharsetDecoder replaceWith (String newReplacement) 
    public final String replacement() 
    public final CharsetDecoder reset() 
    public CodingErrorAction unmappableCharacterAction() 
}
3.4 CharsetEncoder

CharsetEncoder 实例将字符序列转换为编码的字节序列,该类的实例也是有状态的。

public abstract class CharsetEncoder 
{ 
    public final float averageBytesPerChar() 
    public boolean canEncode (char c) 
    public boolean canEncode (CharSequence cs) 
    public final Charset charset() 
    public final java.nio.ByteBuffer encode (java.nio.CharBuffer in) 
        throws CharacterCodingException 
    public final CoderResult encode (java.nio.CharBuffer in, 
java.nio.ByteBuffer out, boolean endOfInput) 
    public final CoderResult flush (java.nio.ByteBuffer out) 
    public boolean isLegalReplacement (byte [] repl) 
    public CodingErrorAction malformedInputAction() 
    public final float maxBytesPerChar() 
    public final CharsetEncoder onMalformedInput (CodingErrorAction 
newAction) 
    public final CharsetEncoder onUnmappableCharacter (CodingErrorAction 
newAction) 
    public final CharsetEncoder replaceWith (byte [] newReplacement) 
    public final byte [] replacement() 
    public final CharsetEncoder reset() 
    public CodingErrorAction unmappableCharacterAction() 
}
3.5 CoderMalfunctionError

CharsetEncoder.encode() CharsetDecoder.decode() 方法捕获到来自低级别 encodeLoop() decodeLoop() 方法的意外异常时,抛出 CoderMalfunctionError

public class CoderMalfunctionError 
    extends Error 
{ 
    public CoderMalfunctionError (Exception cause) 
}
3.6 CoderResult

CoderResult 对象由 CharsetDecoder.decode() CharsetEncoder.encode() 返回,用于指示编码操作的结果。

public class CoderResult 
{ 
    public static final CoderResult OVERFLOW 
    public static final CoderResult UNDERFLOW 

    public boolean isError() 
    public boolean isMalformed() 
    public boolean isOverflow() 
    public boolean isUnderflow() 
    public boolean isUnmappable() 
    public int length() 
    public static CoderResult malformedForLength (int length) 
    public void throwException() 
        throws CharacterCodingException 
    public String toString() 
    public static CoderResult unmappableForLength (int length) 
}
3.7 CodingErrorAction

CodingErrorAction 类是一个类型安全的枚举。命名实例传递给 CharsetDecoder CharsetEncoder 对象,以指示遇到编码错误时应采取的操作。

public class CodingErrorAction 
{ 
    public static final CodingErrorAction IGNORE 
    public static final CodingErrorAction REPLACE 
    public static final CodingErrorAction REPORT 

    public String toString() 
}
3.8 其他异常
  • IllegalCharsetNameException :当提供的字符集名称不符合字符集命名规则时抛出。字符集名称必须由 ASCII 字母(大写或小写)、数字、连字符、冒号、下划线和句点组成,并且第一个字符必须是字母或数字。
public class IllegalCharsetNameException 
    extends IllegalArgumentException 
{ 
    public IllegalCharsetNameException (String charsetName) 

    public String getCharsetName() 
}
  • MalformedInputException :在编码操作中检测到格式错误的输入时抛出。
public class MalformedInputException 
    extends CharacterCodingException 
{ 
    public MalformedInputException (int inputLength) 

    public int getInputLength() 
    public String getMessage() 
}
  • UnmappableCharacterException :当编码器或解码器无法映射一个或多个来自有效输入序列的字符时抛出。
public class UnmappableCharacterException 
    extends CharacterCodingException 
{ 
    public UnmappableCharacterException (int inputLength) 

    public int getInputLength() 
    public String getMessage() 
}
  • UnsupportedCharsetException :当请求的字符集不受当前 JVM 环境支持时抛出。
public class UnsupportedCharsetException 
    extends IllegalArgumentException 
{ 
    public UnsupportedCharsetException (String charsetName) 

    public String getCharsetName() 
}
4. java.nio.charset.spi 包中的类

java.nio.charset.spi 包包含一个用于字符集服务提供程序接口机制的类。

4.1 CharsetProvider

CharsetProvider 便于将 Charset 实现安装到运行的 JVM 中。具体子类的全限定名应列在类加载器类路径中的 META - INF/services/java.nio.charset.spi.CharsetProvider 文件中,以便通过服务提供程序接口机制激活它们。

public abstract class CharsetProvider 
{ 
    public abstract java.nio.charset.Charset charsetForName (String 
charsetName); 
    public abstract java.util.Iterator charsets(); 
}
5. java.util.regex 包中的类

java.util.regex 包包含用于正则表达式处理的类。

5.1 Matcher

Matcher 对象是一个有状态的匹配引擎,用于检查输入字符序列以检测正则表达式匹配,并提供有关成功匹配的信息。

public final class Matcher 
{ 
    public Matcher appendReplacement (StringBuffer sb, String replacement) 
    public StringBuffer appendTail (StringBuffer sb) 
    public int end() 
    public int end (int group) 
    public boolean find() 
    public boolean find (int start) 
    public String group() 
    public String group (int group) 
    public int groupCount() 
    public boolean lookingAt() 
    public boolean matches() 
    public Pattern pattern() 
    public String replaceAll (String replacement) 
    public String replaceFirst (String replacement) 
    public Matcher reset() 
    public Matcher reset (CharSequence input) 
    public int start() 
    public int start (int group) 
}
5.2 Pattern

Pattern 类封装了一个编译后的正则表达式。

public final class Pattern 
    implements java.io.Serializable 
{ 
    public static final int CANON_EQ 
    public static final int CASE_INSENSITIVE 
    public static final int COMMENTS 
    public static final int DOTALL 
    public static final int MULTILINE 
    public static final int UNICODE_CASE 
    public static final int UNIX_LINES 

    public static Pattern compile (String regex) 
    public static Pattern compile (String regex, int flags) 
    public int flags() 
    public Matcher matcher (CharSequence input) 
    public static boolean matches (String regex, CharSequence input) 
    public String pattern() 
    public String [] split (CharSequence input) 
    public String [] split (CharSequence input, int limit) 
}

下面用表格总结 java.util.regex Matcher Pattern 类的主要方法:
| 类名 | 方法名 | 方法描述 |
| ---- | ---- | ---- |
| Matcher | appendReplacement | 将匹配到的内容替换并追加到 StringBuffer 中 |
| Matcher | appendTail | 将剩余的输入追加到 StringBuffer 中 |
| Matcher | find | 查找输入序列中是否有匹配的子序列 |
| Matcher | group | 返回匹配到的子序列 |
| Pattern | compile | 编译正则表达式 |
| Pattern | matcher | 创建一个 Matcher 对象用于匹配输入序列 |
| Pattern | matches | 检查整个输入序列是否与正则表达式匹配 |

再用 mermaid 流程图展示 java.util.regex 中使用正则表达式匹配的流程:

graph TD;
    A[开始] --> B[编译正则表达式为Pattern对象];
    B --> C[创建Matcher对象];
    C --> D{是否找到匹配};
    D --> |是| E[处理匹配结果];
    E --> F{是否继续查找};
    F --> |是| D;
    F --> |否| G[结束];
    D --> |否| G;

通过对这些包中类和异常的学习,我们可以更好地处理 Java 编程中的文件操作、字符编码以及正则表达式匹配等问题,提高代码的健壮性和功能的完整性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值