第九章、 枚举和注解

第九章、 枚举和注解

9.1 对IDEA的某些功能介绍

怎么搞:一创建类,类的头部出现一些注释信息。

在这里插入图片描述
在设置–>编辑器–>文件和代码模版中includes中。
在这里插入图片描述
在设置完后,像图中这个@version带有背景颜色,怎么把它去掉。
在这里插入图片描述
将它添加为标记即可。如下图设置:

在这里插入图片描述

9.2 自定义类实现枚举

9.2.1 枚举类的引出

要求创建季节(Season)对象,有两个字符串,第一个字符串是季节name,第二个字符串是对这个季节的描述desc;并设置相关的构造器和setter和getter方法。创建四个季节的对象,给出描述。

  1. 默认写法:
    定义类,创建对象去设置季节。
  2. 引出问题:
    因为对于季节而言,它的对象(具体值),是固定的四个,是不会改变的。
    那么问题来了:既然季节是固定值,那么上面的对象是可以修改的,也可以创建其他对象:比如::白天,蓝色,这是不符合逻辑的。
  3. 提出解决方案:
    引出枚举类–>固定值,不允许外部修改和添加
package chapter9.enum_;

public class Enumeration01 {
    public static void main(String[] args) {
        //默认写法
        Season spring = new Season("春天", "温暖");
        Season summer = new Season("夏天", "炎热");
        Season autumn = new Season("秋天", "清爽");
        Season winter = new Season("冬天", "寒冷");
        //因为对于季节而言,它的对象(具体值),是固定的四个,是不会改变的
        //那么问题来了:既然季节是固定值,那么上面的对象是可以修改的,也可以创建其他对象:比如::白天,蓝色,这是不符合逻辑的。
        //因此,就引出枚举类-->固定值,不允许外部修改和添加
    }
}

class Season{
    private String name;
    private String desc;

    public Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
  1. 枚举的基本介绍:
    (1). 创建Season对象有如下特点:
    ① 季节的值是有限的几个值(spring, summer, autumn, winter)
    ② 只读,不需要修改
    (2). 枚举
    ① 枚举对应英文(enumeration, 简写enum)
    ② 枚举是一组常量的组合
    ③ 这里可以理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。
    (3). 枚举的两种实现方式
    ① 自定义类实现枚举
    ② 使用关键字enum实现枚举

9.2.2 自定义类实现枚举—应用案例

  1. 不需要提供setXxx方法,因为枚举对象值通常为只读。
  2. 对枚举对象/属性使用final+static共同修饰,加final是为了实现底层优化。
  3. 枚举对象名通常使用全部大写,常量的命名规范。
  4. 枚举对象根据需要,也可以有多个属性。
package chapter9.enum_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class Enueration02 {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);//Season{name='春天', desc='温暖'}
    }
}

//定义枚举实现
class Season{
    private String name;
    private String desc;

    public final static Season SPRING=new Season("春天", "温暖");
    public final static Season SUMMER=new Season("夏天", "炎热");
    public final static Season AUTUMN=new Season("秋天", "清爽");
    public final static Season WINTER=new Season("秋天", "清爽");

    //1.私有化构造器,防治直接new
    //2.去掉setXxx方法,防治属性被修改
    //3.在Season 内部,直接创建固定的对象
    private Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
  1. 小结:进行自定义类实现枚举,有如下特点:
    (1). 构造器私有化
    (2). 本类内部创建一组对象
    (3). 对外暴露对象(通过为对象添加public final static修饰)
    (4). 可以提供get方法,但是不能提供set方法

9.3 enum关键字实现枚举

  1. 将前面的代码改为使用enum实现枚举
package chapter9.enum_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class Enumeration03 {
    public static void main(String[] args) {
        System.out.println(Season2.AUTUMN);//Season2{name='秋天', desc='清爽'}
    }
}

enum Season2{
    //使用enum关键字 实现枚举类
    //1.将这个public final static Season SPRING=new Season("春天", "温暖");简化成SPRING("春天", "温暖"),
    //2.如果有多个常量(对象),使用逗号(,)间隔即可。语法格式:常量名(实参列表)
    //3. 如果使用enum 来实现枚举,要求将定义常量对象,写在最前面
    SPRING("春天", "温暖"),
    SUMMER("夏天", "炎热"),
    AUTUMN("秋天", "清爽"),
    WINTER("秋天", "清爽");

    private String name;
    private String desc;
    Season2(String name, String desc) {
        this.name=name;
        this.desc=desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season2{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
  1. enum关键字实现枚举注意事项
    (1). 当使用enum关键字开发一个枚举类时,默认会继承Enum类,而且还是一个final类。可以使用javap对.class进行反编译即查看源码(javac是编译生成.class文件)。
    (2). 传统的public final static Season SPRING=new Season(“春天”, “温暖”);简化成SPRING(“春天”, “温暖”),这里必须知道,它调用的是哪个构造器。
    (3). 如果使用无参构造器 创建枚举对象,则实参列表和小括号都可以省略
    (4). 当有多个枚举对象时,使用逗号(,)间隔最后由一个分号结尾。
    (5). 枚举对象必须放在枚举的行首。
    在这里插入图片描述
  2. 练习
    (1). 判断下面代码是否正确,并说明表示的含义?
    enum Gender{
    BOY,GIRL;
    }
    解析:正确
    有一个枚举类Gender,没有属性
    有两个枚举对象BOY,GIRL ,使用的默认的无参构造器

(2). 写出下面代码的输出是什么?

package chapter9.enum_;

import java.sql.SQLOutput;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class EnumExercise01 {
    public static void main(String[] args) {
        Gender boy=Gender.BOY;
        Gender boy2=Gender.BOY;
        System.out.println(boy);//boy本质是对象,直接输出默认调用该对象的toString方法,若没有重写,就会调用父类Enum的toString方法,输出BOY
        System.out.println(boy2==boy);//boy本质是静态对象,== 用于判断是不是共一个对象,都是BOY对象,故输出true
    }
}
enum Gender{
    BOY,GIRL;
}

在这里插入图片描述
4. enum常用方法说明
说明:使用关键字enum时,会隐式继承Enum类,这样就可以使用Enum类的相关方法。

在这里插入图片描述

方法名详细描述
valueOf传递枚举类型的Class对象和枚举常量名称给静态方法valueOf,会的到与参数匹配的枚举常量
toString得到当前枚举常量的名称。可以通过重写这个方法来使得到的结果更加易读
equals在枚举类型中可以直接使用来比较两个枚举常量是否相等。Enum提供的这个equals()方法,也是直接使用实现的。它的存在是为了在Set、List和Map中使用。注意,equals是不可变的。
hashCodeEnum实现了hashCode()来和equals()保持一致。它也是不可变的。
getDeclaringClass得到枚举常量所属枚举类型的Class对象。可以用它来判断两个枚举常量是否属于同一枚举类型。
name得到当前枚举常量的名称。建议优先使用toString()。
ordinal得到当前枚举常量的次序
compareTo枚举类型实现了Comparable接口,这样可以比较两个枚举常量的大小(按照声明的顺序排列)
clone枚举类型不能被Clone。为了防治子类实现克隆方法,Enum实现了一个仅抛出CloneNotSupportedException异常的不变Clone()。
  1. enum常用方法应用实例
    (1). toString:Enum类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的是属性信息。
    (2). name:返回当前对象名(常量名),子类中不能重写
    (3). ordinal:返回当前对象的位置号,默认重0开始
    (4). values:返回当前枚举类中的所有常量
    (5). valueOf:将字符串转成枚举对象,要求字符串必须为已有的常量名,否则报异常!
    (6). CompareTo:比较两个枚举常量,比较的就是位置号。
package chapter9.enum_;

import java.util.Arrays;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class EnumMethod {
    public static void main(String[] args) {
        Season3 autumn=Season3.AUTUMN;
        //(1)  toString:Enum类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的是属性信息。
        System.out.println("toString方法的使用=  "+autumn);
        //(2)  name:返回当前对象名(常量名),子类中不能重写
        System.out.println("name方法的使用=  "+autumn.name());
        //(3)  ordinal:返回当前对象的位置号,默认重0开始
        System.out.println("ordinal方法的使用=  "+autumn.ordinal());
        //(4)  values:返回当前枚举类中的所有常量,是个Season3[]
        Season3[] s=Season3.values();
        System.out.println("values方法的使用=   ");
        for(Season3 season3:s){
            System.out.println(season3);
        }
        //(5)  valueOf:将字符串转成枚举对象,要求字符串必须为已有的常量名,否则报异常!
        System.out.println("valueOf方法的使用=  "+Season3.valueOf("AUTUMN"));
        //(6)  CompareTo:比较两个枚举常量,比较的就是位置号。self.ordinal - other.ordinal;
        Season3 spring=Season3.SPRING;
        System.out.println(spring.compareTo(autumn));
    }
}
enum Season3{
    SPRING("春天", "温暖"),
    SUMMER("夏天", "炎热"),
    AUTUMN("秋天", "清爽"),
    WINTER("秋天", "清爽");

    private String name;
    private String desc;
    Season3(String name, String desc) {
        this.name=name;
        this.desc=desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season3{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
/*
toString方法的使用=  Season3{name='秋天', desc='清爽'}
name方法的使用=  AUTUMN
ordinal方法的使用=  2
values方法的使用=   
Season3{name='春天', desc='温暖'}
Season3{name='夏天', desc='炎热'}
Season3{name='秋天', desc='清爽'}
Season3{name='秋天', desc='清爽'}
valueOf方法的使用=  Season3{name='秋天', desc='清爽'}
-2
*/
  1. 练习
    (1). 声明Week枚举类,其中包含了星期一至星期日之间的定义:MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
    (2). 使用values返回所有的枚举数组,并遍历,输出。
package chapter9.enum_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class EnumExercise02 {
    public static void main(String[] args) {
        Week[] weeks=Week.values();
        System.out.println("======所有星期的信息如下======");
        for(Week week:weeks){
            System.out.println(week);
        }
    }
}
enum Week{
    MONDAY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期日");

    private String name;

    Week(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return  name;
    }
}
/*
======所有星期的信息如下======
星期一
星期二
星期三
星期四
星期五
星期六
星期日
*/
  1. enum实现接口
    (1). 使用enum关键字后,就不能再继承其他类了,因为enum会隐式继承Enum,而Java是单继承机制
    (2). 枚举类和普通类一样,可以实现接口,如下形式:
    enum 类名 implement 接口1,接口2{}
package chapter9.enum_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class EnumDetail {
    public static void main(String[] args) {
        Weekend.HI.hi();//周末好~~
    }
}
interface Iaa{
    void hi();
}
enum Weekend implements Iaa{
    HI;
    @Override
    public void hi() {
        System.out.println("周末好~~");
    }
}

9.4 JDK内置的基本注解类型

  1. 注解的理解
    (1). 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。
    (2). 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相等与嵌入在代码中的补充信息。
    (3). 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用进程的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。

  2. 基本的Annotation介绍
    使用Annotation时要在其面前增加@符号,并把该Annotation当做一个修饰符使用。用于修饰它支持的程序元素。
    三个基本的Annotation:
    (1). @Override:限定某个方法,是重写父类的方法,该注解只能用于方法
    (2). @Deprecated:用于表示某个程序元素(类、方法等)已过时
    (3). @SuppressWarnings:抑制编译器警告

  3. 基本的Annotation(@Override)应用案例
    (1). @Override:限定某个方法,是重写父类的方法,该注解只能用于方法
    (2). @Override表现指定重写父类的方法(从编译层面验证)。
    (3). 如果真的重写了父类方法,而不写@Override,也不会报错
    (4). @Override只能修饰方法,不能修饰其他类、包、属性等等。
    (5). 查看@Override注解源码为@Target (ElementType.METHOD)说明只能修饰方法
    (6). @Target是修饰注解的注解。如果一个注解修饰另一个注解,称为元注解

package chapter9.annotation;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class Override_01 {
    public static void main(String[] args) {
        new Son().say();
    }
}
class Father{
    public void say(){
        System.out.println("Father say.....");
    }
}
class Son extends Father{
    //1.@Override写在say方法上,表示子类的say方法是重写了父类的say
    //2.如果这个没有写@Override,也没事,它还是重写了父类的say,那@Override有什么用呢?
    //3.用处:其实就是编译器会进行一个语法的校验,如果在一个方法上写@Override,编译器会检查这个方法是不是重写父类的方法,
    //如果是则编译通过,如果不是,就会出现编译错误。
    //4.查看源码,如果发现@interface,则表示一个注解类
    /*
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
     */
    @Override
    public void say() {
        System.out.println("Son say.......");
    }
}
//输出:Son say.......
  1. 基本的Annotation(@Deprecated)应用案例
    (1). @Deprecated:用于表示某个程序元素(类、方法等)已过时
    (2). 可以修饰方法、类、字段、包、参数等等
    (3). @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
    (4). @Deprecated的作用可以做到新旧版本的兼容和过渡
package chapter9.annotation;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class Deprecated_ {
    public static void main(String[] args) {
        A a = new A();
        a.hi();
    }
}
//@Deprecated修饰某个元素,表示该元素已经过时
//即不再推荐使用,但是仍然可以使用
@Deprecated
class A{
    public int n1=29;
    @Deprecated
    public void hi(){}
}
  1. 基本的Annotation(@SuppressWarnings)应用案例
    (1). @SuppressWarnings:抑制编译器警告
    (2). 生成@SuppressWarnings时,不用背,直接点击左侧的黄色提示,就可以选择(注意可以指定生成位置)
package chapter9.annotation;

import java.util.ArrayList;
import java.util.List;

/**
 *@aim java基础学习
 *@note java笔记
 */

//1.当我们不希望看到这些警告的时候,可以使用SuppressWarnings注释来抑制警告信息
//2.在{""}中,可以写入我们希望抑制(不显示)警告信息
//3.可以指定警告类型
//4.关于@SuppressWarnings 作用范围是和放置的位置密切相关,如果只想抑制某个方法中的警告,就放置在这个方法上。
//5.由下面源码得:
// (1).可以放置的位置:{TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE}
// (2).该注解类接收一个字符串数组 , 比如:{"rawtypes","unused","unchecked"}
    /*
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
        @Retention(RetentionPolicy.SOURCE)
        public @interface SuppressWarnings {
            String[] value();
        }
        TYPE:表示类、接口、枚举类型。
        FIELD:表示类中的字段(成员变量)。
        METHOD:表示类中的方法。
        PARAMETER:表示方法的参数。
        CONSTRUCTOR:表示类的构造方法。
        LOCAL_VARIABLE:表示方法或代码块中的局部变量。
        MODULE:表示模块,这是 Java 9 引入的概念,用于模块化系统。
     */
@SuppressWarnings({"rawtypes","unused","unchecked"})
public class SuppressWarning_ {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add("mark");
        list.add("jack");
        list.add("huck");
        list.add("zach");
        int i;
        System.out.println(list.get(1));//jack
    }
}
  1. 警告类型:

(1). @SuppressWarnings(“all”):抑制所有警告
(2). @SuppressWarnings(“boxing”):抑制与封装/拆装作业相关的警告
(3). @SuppressWarnings(“cast”):抑制与强制转型作业相关的警告
(4). @SuppressWarnings(“dep-ann”):抑制与淘汰注释相关的警告
(5). @SuppressWarnings(“deprecation”):抑制与淘汰的相关警告
(6). @SuppressWarnings(“fallthrough”):抑制与switch语句中遗漏break相关的警告
(7). @SuppressWarnings(“finally”):抑制与未返回finally块相关的警告
(8). @SuppressWarnings(“hiding”):抑制与隐藏变量的局部变量相关的警告
(9). @SuppressWarnings(“incomplete-switch”):抑制与switch语句(enum case)中遗漏项相关的警告
(10). @SuppressWarnings(“javadoc”):抑制与javadoc相关的警告
(11). @SuppressWarnings(“nls”):抑制与非NLS字符串文字相关的警告
(12). @SuppressWarnings(“null”):抑制与空值分析相关的警告
(13). @SuppressWarnings(“rawtypes”):抑制与使用raw类型相关的警告
(14). @SuppressWarnings(“resource”):抑制与使用Closeable类型的资源相关的警告
(15). @SuppressWarnings(“restriction”):抑制与使用不建议或禁止引用相关的警告
(16). @SuppressWarnings(“serial”):抑制与可序列化类遗漏serialVersionUID字段相关的警告
(17). @SuppressWarnings(“static-access”):抑制与静态访问不正确相关的警告
(18). @SuppressWarnings(“static-method”):抑制与可能声明为static的方法相关的警告
(19). @SuppressWarnings(“super”):抑制与覆盖方法相关但不含super调用的警告
(20). @SuppressWarnings(“synthetic-access”):抑制与内部类的访问未优化相关的警告
(21). @SuppressWarnings(“sync-override”):抑制因覆盖同步方法而遗漏同步化的警告
(22). @SuppressWarnings(“unchecked”):抑制与未检查的作业相关的警告
(23). @SuppressWarnings(“unqualified-field-access”):抑制与字段访问不合规相关的警告
(24). @SuppressWarnings(“unused”):抑制与未使用的代码及废弃的代码相关的警告

9.5 元注解(了解)

  1. 元注解的基本介绍
    (1). JDK的元Annotation用于修饰其他的Annotation
    (2). 元注解:本身作用不大,就是在看源码时,可以知道它是做什么的即可。
    (3). 元注解的种类(了解)
    ① @Retention:指定注解的作用范围,三种SOURCE、CLASS、RUNTIME
    ② @Target:指定注解可以在那些地方使用
    ③ @Documented:指定该注解是否会再Javadoc体现
    ④ @Inherited:子类会继承父类注解

  2. @Retention注解
    说明:
    只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间,@Retention包含一个RetentionPolicy类型的成员变量,使用@Retention时必须为该value成员变量指定值:
    (1). RetentionPolicy.SOURCE:编译器使用后,直接丢弃这个策略的注解
    (2). RetentionPolicy.CLASS:编译器将该注解记录在class文件中,当运行Java程序是,JVM不会保留注解。这是默认值
    (3). RetentionPolicy.RUNTIME:编译器把注解记录在class文件中,当运行Java程序时,JVM会保留注解。程序可以通过反射获取该注解。
    注意:Override的作用域在SOURCE,当编译器编译时生效,不会写入到.class,也不会在runtime(运行时)生效。

  3. @Target注解
    说明:
    用于修饰Annotation定义,用于指定被修饰的Annotation用于修饰那些程序元素。@Target也包含一个名为value的成员变量。

  4. @Documented注解
    说明:
    @Documented:用于指定被改元Annotation修饰的Annotation类将被javadoc工具提取成文档,即在生成文档时,可以看到该注解。
    定义为Documented的注解必须设置Retention值为RUNTIME。

  5. @Inherited注解
    说明:
    被它修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。

9.6 本章作业

  1. 编程题(枚举类)
    (1). 创建一个Color枚举类
    (2). 有RED、BLUE、BLACK、YELLOW、GREEN这五个枚举值/对象
    (3). Color有三个属性redValue、greenValue、blueValue
    (4). 创建构造方法,参数包括这三个属性
    (5). 每个枚举值都要给这三个属性赋值,三个属性对应的值分别是:red:255,0,0;blue:0,0,255;black:0,0,0;yellow:255,255,0;green:0,255,0
    (6). 定义接口,里面有方法show,要求Color实现该接口
    (7). Show方法中显示三属性的值
    (8). 将枚举对象在switch语句中匹配使用
    接口interfaceShow
package chapter9.work_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public interface interfaceShow {
    String show();
}

类Color

package chapter9.work_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public enum Color implements interfaceShow{
    RED(255,0,0),
    BLUE(0,0,255),
    BLACK(0,0,0),
    YELLOW(255,255,0),
    GREEN(0,255,0);
    private int redValue;
    private int greenValue;
    private int blueValue;

    Color(int redValue, int greenValue, int blueValue) {
        this.redValue = redValue;
        this.greenValue = greenValue;
        this.blueValue = blueValue;
    }

    @Override
    public String show() {
        return "属性值="+redValue+","+greenValue+","+greenValue;
    }
}

测试类Task02

package chapter9.work_;

/**
 * @aim java基础学习
 * @note java笔记
 */
public class Task02 {
    public static void main(String[] args) {
        Color green=Color.GREEN;
        System.out.println(green.show());
        //swith() 中,放入枚举对象
        //每个case后,直接放上枚举类中,定义的枚举对象即可。
        switch(green){
            case RED:
                System.out.println("匹配到红色");
                break;
            case BLUE:
                System.out.println("匹配到蓝色");
                break;
            case BLACK:
                System.out.println("匹配到黑色");
                break;
            case YELLOW:
                System.out.println("匹配到黄色");
                break;
            case GREEN:
                System.out.println("匹配到绿色");
                break;
            default:
                System.out.println("没有匹配到颜色");
        }
    }
}
//属性值=0,255,255
//匹配到绿色
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值