java基础

java基础

声明:

该文档参考于b站老杜java视频视频地址: https://www.bilibili.com/video/BV1Rx411876f/?spm_id_from=333.337.search-card.all.click&vd_source=bc31f1a530d129ce331819489ac66472
文中图片参考于视频,如有侵权,联系删除qq:1945478169

1.5万字记录

java零基础
JDK、JRE、JVM区别

JDK是java语言的软件开发工具包

JRE是java程序运行时所需要的环境及其类库

JVM是java虚拟机,java程序运行在JVM上面

JDK包含JRE 、JRE包含JVM

java语言的特性

简单性、

面向对象、

健壮性:java语言具有gc垃圾回收机制,在特定时机会回收/释放垃圾数据

多线程、

可移植性/跨平台:java程序是直接运行在JVM上,不直接与操作系统打交道
在这里插入图片描述

java的加载与执行

在这里插入图片描述

1.windows和linux编译生成为class字节码文件是一样的,所以一次编写,到处运行。

2.一个java文件可以生成多个class文件。

3.Windows中的java文件生成的class文件可以放到Linux上直接运行,不需要拷贝源代码。

4.JVM会对class文件解释成01文件,交给操作系统运行

5.运行阶段在JRE进行

6.javac负责编译,java负责运行,java后面只能跟类名

7.运行开始时类加载器会去找字节码文件,找到给JVM装载

8.可配置系统环境变量path使得dos窗口能够使用javac,java命令

9.系统变量作用于全部用户,用户变量作用于个别用户

10.JAVA_HOME环境变量,学习到javaweb的时候需要配置,tomcat回去找这个环境变量

java HelloWorld命令都发生了什么

1.先启动JVM

2.JVM回去启动类加载器,类加载器回去硬盘上去找类对应的字节码文件

3.类加载器如果找不到对应的字节码文件,会报错:ClassNotFoundException找不到或无法加载主类,如果找到的话,就会把字节码文件装载到JVM中,JVM将字节码解释为二进制文件交给操作系统处理

classpath环境变量

给类加载器制定一个路径,让类加载器去指定的路径下去加载字节码文件,需要设置一个环境变量classpath(java特有的),是给类加载器指路的

JDK新特性java运行

java直接加java源文件路径,可直接运行,不生成字节码文件

java中的注释

注释在程序编写中非常重要!!编译生成的class文件不包含注释,写注释是java软件工程师的基本素养

/* 注释内容*/ : 多行注释 // : 单行注释

/**

*@version 1.0

*@author: gjq

*/ 此为javadoc注释,这个注释会被bin目录下javadoc.exe识别,生成帮助文档

public class 与class区别

public 修饰的类不是必须的,可以没有,如果有的话类名必须是文件名,public修饰的类只能有一个,一个class 定义就会生成一个字节码文件

每一个类都可以添加入口(main方法)

数据类型

在这里插入图片描述

整数型

short和char实际上容量相等,不过char 可以表示更大的数字。因为char表示的是文字,文字没有正负之分,所以char可以表示更大的数字

字符编码其实本质上就是一本字典,该字典中描述了文字与二进制之间的对照关系

‘a’–>(ASCII编码)97–>01100001–>'(ASCII解码)‘a’ 'A '–>65 如果编码和解码采用的不是一种编码就会产生乱码

中文的编码:GBK 繁体中文:big5编码 java语言支持全球所有的文字,编码为UTF-8、UTF-16

字符型char:char可以存储一个汉字(一个汉字占用两个字节)使用’ '括起来,中间只能放一个字符

‘\’(反斜杠)为转义字符,'\t’为制表符tab '\n’为换行字符,换一行 System.out.println()是打印完再换行

在控制台打印输出 ’ System.out.println(‘\’');

char x='\u4e2d’表示后面是一个字符的unicode编码,是十六进制的

int b=010:表示八进制int b=0x10:表示十六进制 b=0b10:表示二进制

在任何情况下整数型的字面量被当做int类型处理 long i=100L 表示将100L 类型赋值给i(不存在类型转换)

long b=100;小容量会自动转换为大容量,自动类型转换,(存在类型转换)

long e=2147483648;出错2147483648默认看成int类型,该数超过int类型范围,要在数2147483648后面加L

long x=100L;int y=x;在java中,大容量不能直接赋值给小容量,值可能会有损失,要想编译通过要加强制类型转换符进行强制转换int y=(int)x编译通过了,但可能会有损失

100L:00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100100

强制转换为int会自动砍掉前面四个字节 : 00000000 00000000 00000000 01100100

byte b=300编译不通过因为int转换为byte可能会有损失,但如果赋值int类型大小在byte范围内就不用强制转换,short同理。

整数没有超过char的范围可直接赋值给char类型 char c=97打印出a,char c=65536:报错

小结论:一个整数没有超过byte ,short,char类型范围是可直接赋值

char c1='a';byte b=1;System.out.println(c1+b);结果是98 short c2=c1+b;报错,只有赋值的时候后面写确切的数字时,才会不报错,后面是运算时时编译器不能确定运算后的结果,所以不能

char c='a'+100;:可以 char c='a';c=c+100;:不可以

byte ,char,short做混合运算的时候是各自转换成int再运算

long a=10L;char c='a';long s=100;int i=30;System.out.println(a+c+s+i);运算后的结果是long 类型,多种数据类型做混合运算的时候,最终的结果是“最大容量类型”。char+short+byte除外,这些类型会自动转换为int运算

浮点型

float(单精度) 4个字节 double(双精度): 8个字节,在财务方面double可能也不够用,有一个精度更高的类型在java.math.BigDecimal类型,float 和double 存储的都是近视值, float可以直接赋值给double

任意一个浮点型容量都大于整数型 float>long!!

java中任何一个浮点型类型默认被当做double处理。如果相当做float处理后面加f/F float f=3.1415926F,或者强制类型转换int i=10.0/5出错:先将5转换为double类型,运算结果就是double型

多种数据类型运算时,各自转换成容量最大的哪一种再做运算 ,float与long int…运算结果是float类型,double与long int…运算结果是double类型

短路与与短路或

&&:短路与,||:短路或

&&:当左边为FALSE是就不再运算了 ,而&会两边都执行 ||:当左边为TRUE是就不再运算了 ,而|会两边都执行

三目运算符

布尔表达式?表达式1:表达式2

boolean sex=false; char rs= sex?'男':'女';

字符串连接运算符

+运算符 作用1:求和,作用2:字符串的拼接

in k=10;k=k++–>int k=10;int temp=k;k++;k=temp; k的结果是10(在C++中为11)

接收用户输入

java.util.Scanner scanner =new java.util.Scanner(System.in);

scanner.nextInt();接收一个int类型数据,如果不是int 类型,会出现异常InputMismatchException

如果一开始输入int类型数据,想再输入其他类型的数据需要再创建一个Scanner对象

s.next():输入一个String类型数据

可以采用import java.util.Scanner简化

swtich多分支语句

default: 默认情况 case 合并问题 :case 1: case 2: case 3: java语句 break;

switch 本质上只支持int和String,但是byte short char 也可以使用,会进行自动类型转换

不支持float double long 类型

循环

当多个循环嵌套的时候break 会退出最近的那一个 ,可以给循环语句命名 使用break + 循环名字退出指定循环,例如:

f1:for(int i=0;i<10;i++) { for(int j=0;j<10;j++) { break f1; }

}

方法

当重复实现一个功能的时候就可以使用方法(c中叫做函数)了 ,方法的定义(方法定义在类体当中):

public static 返回值类型 方法名(参数){java语句}

public static void main(){a();int i=1;}public static int a(){return 1;}

main方法调用a方法,a方法的返回值返回给main方法,在调用期间main方法会一直停在第一行直至a方法执行完成再执行下面的语句。

方法名命名规范,要求首字母小写,后面每一个单词首字母大写(驼峰命名方式)

调用方法:类名.方法名(实参数列表);调用时实参列表与方法的形参列表要一一对应

当调用的方法在当前调用的的类中的时候调用方法可以直接使用方法名调用,如果不在调用的方法不在同一类中必须使用类名.方法名(实参数列表)进行调用

JVM内存结构

在这里插入图片描述

类加载器classLoader将硬盘上的class文件装载到JVM时候,会将字节码文件放到方法区中,也就是说方法区中存储的是代码片段,因为类要加载,所以方法区当中最先有数据

方法调用的时候,该方法需要的内存空间在栈中分配,方法不调用不在栈中分配空间,调用一个方法就在栈内存中入栈,一个方法执行完成之后弹栈

在这里插入图片描述

方法的重载

不使用重载机制的话,方法实现相似功能,会使代码不美观,程序员需要记忆更多的方法名称。 重载的优点:代码整齐,功能相似的,可以让方法名相同,便于以后的代码编写,调用重载方法时会自动匹配方法

java编译器会通过方法名进行区分方法,如果方法名相同则会根据形参类型和多少进行区分

1.在同一类当中 2.方法名相同 3.参数列表不同 3.1 参数个数不同 3.2参数类型不同 3.3 参数顺序不同

方法重载跟返回值类型、修饰值列表、变量名无关

System.out.println()就是用了方法重载

方法的递归

方法自己调用自己就是递归

在这里插入图片描述

在这里插入图片描述

此程序会出现StackOverFlowError栈溢出错误,所以递归必须要有结束条件,递归耗用的内存比较大,在极少的情况下不用递归程序无法实现

如果出现栈溢出错误,如何处理

1.先检查递归的结束条件

2.手动调整JVM的栈内存大小

3.如果还是出现错误,只能继续扩大栈的内存大小(java -x)

在这里插入图片描述

面向对象
面向对象和面向过程的区别

对于c语言来说是完全面向过程的,C++是半面向对象的,对于java来说是完全面向对象的

面向过程:

面向过程的注重的是实现这个功能的步骤,第一步干什么,第二步干什么,也注重实心功能的因果关系

缺点:每一步与每一步的因果关系,其中A步骤因果关系到B步骤,A和B联合起来形成一个子模块,子模块和子模块又因为因果关系结合在一起,其中任何一个因果关系出现问题,整个系统就会出现问题。代码与代码之间耦合度太高,扩展力差,采用面向过程开发一台计算机就是一体机,任何一个部位出现问题,整台计算机就不能用了

优点:对于小型项目采用过程进行开发,效率较高

面向对象:采用面向对象开发更符合人类的思维方式,面向对象就是将现实世界分割成不同的单元,然后都实现成对象,然后驱动一下,让各个对象之间协作起来形成一个系统,耦合度低,扩展力强

采用面向对象开发一台计算机,CPU是一个对象,内存条是一个对象…任何一个坏了都可以更换

合适的案例:蛋炒饭(面向过程),盖饭(面向对象)

OOA(Analysis) :面向对象分析 OOD:面向对象设计 OOP:面向对象编程 PM:项目监管人

面向对象的三大特征:封装、继承、多态

类和对象

类:现实世界并不存在,是一种抽象的概念,现实世界中某些事物有共同的特征,将这些共同的特征抽取出来,就形成了类,多个对象具有共同特征,进行抽取共同特征的过程叫做抽象,类=属性(多见于名词)+方法(多见于动词)

对象(实例):是实际存在的个体,先有类才有对象,通过类创建实例的过程叫做实例化

明星就是一个类,刘德华,宋小宝就算是对象

在这里插入图片描述

java程序员转换桥梁

在这里插入图片描述

类体=属性+方法 属性在代码上以变量形式存在,方法描述动作/行为

方法体内声明的变量叫做局部变量,方法体外面类体里面叫做成员变量(就是属性)

java中所有的类都属于引用数据类型

编译一个java文件,如果java文件中包含其他类,也会自动编译所需的类文件

对象的创建:类名 变量名 =new 类名();

对象和引用

凡是通过new运算符创建的对象都存储在堆内存当中,new 的作用就是在堆内存当中开辟一块空间

对于成员变量来说,没有手动赋值时系统默认赋值,引用数据类型默认为空(String也是),

局部变量必须赋值使用,没有默认值(引用类型也是)。实例变量必须由实例才能引用

实例变量存储在堆内存中对象中,局部变量存储在栈的方法内存当中

Student s1=new Student();Student s2=new Student();

JVM内存图如下:

在这里插入图片描述

Student s1=new Student(); Student s2=s1;s1与s2指向的是同一个对象地址,s1的值是对象在堆内存中的地址,赋给s2的是s1的值

类名和变量名可以使用中文 ,引用不一定是局部变量

Address a=new Address();User u1=new User();u1.address=a;

在这里插入图片描述

在堆内存中new出来的叫做对象,变量u叫做引用,引用就是存储对象内存地址的变量

空指针异常

堆内存中的内容程序员是无权直接操作的,

User u=new User(); u=null;System.out.println(u.id);这时候gc就会把堆内存中的user对象直接回收,java中的gc机制主要针对的是堆内存中的垃圾数据,当堆内存中的一个对象没有任何引用引用的时候 ,就会被gc回收

javac编译器无法检查空指针异常,编译器只检查语法,对空的引用进行实例属性或实例方法操作就会产生空指针异常

方法调用时参数的传递问题

在这里插入图片描述

结果是11和10

参数传递的时候,不管是基本数据类型还是引用类型都传递的是盒子(基本数据类型里面装的是值,引用数据类型指向的是地址,String传递的也是值!!!)里面的值复制一份,传递下去。

在这里插入图片描述

在这里插入图片描述
结果是10和10 ,调用change方法的时候传递的是对象在堆内存中的地址,在change中的p和main中的pl指向的是同一对象

构造方法

当一个类没有提供任何构造方法,系统会自动提供一个无参构造方法(缺省构造器),new 运算符后面其实就是构造方法,调用构造方法必须使用new运算符,构造方法没有返回值类型,构造方法名与类名必须一致,一个类如果手动提供了任意一个构造方法,系统就不会再提供无参构造方法,构造方法支持方法重载,所有构造方法名相同,当调用构造方法的时候,实例变量才会赋值(未手动赋值的赋默认值),建议把无参构造方法手动写出来。只要是方法调用的时候都会在栈中压栈

封装

封装的作用 :1.保证内部结构的安全,2.屏蔽复杂,暴露简单,对代码的调用人员来说,不需要关心代码的复杂实现,只需要通过一个简单的入口访问,调用人员不能访问内部内容,保证安全性

static 关键字

带有static 使用类名.方法名调用,不加static使用引用.方法名使用(需要先new对象) 带static的属于类的范畴,所有static修饰的都可以使用"类名.访问",static修饰的变量称为静态变量,static修饰的方法称为静态方法,成员变量又分为实例变量和静态变量

什么时候使用静态变量?例子:有一个Chinese类有一个country属性,这个国籍属性的值是固定的,这个属性就可以使用static修饰 ,static修饰的静态变量的默认值是在类加载的时候初始化,不需要new对象,静态变量跟类在一起,都在方法区中,静态变量与类关联在一起 ,实例的是一定要用"引用."访问,静态的建议使用"类名."访问,静态变量也可以使用引用调用

什么时候修饰称为静态的?

当某个类的所有对象的某个属性值都是一样的,那么不建议设置为实例变量,浪费空间,建议定义为静态变量。

创建两个Chinese对象的JVM内存图

在这里插入图片描述

在这里插入图片描述

这个不会产生空指针异常,调用country属性的时候实际上还是调用类名访问Chinese.country,如果置空之后调用实例变量或者方法都会产生空指针异常

**静态方法中不能使用实例变量和实例方法,可以使用静态变量和静态方法,实例方法可以使用静态变量和静态方法和实例方法和实例变量,**当一个方法访问了实例变量或者实例方法那么这个方法一定是实例方法。

静态代码块

static{java语句;}在类加载时执行而且只执行一次,一个类当中可以编写多个静态代码块。

用途:所有在我们编写的程序当中,只要是类加载了,请记录一下类加载的日志信息

静态代码块里面只能访问静态方法或者静态变量,如果静态变量定义在静态代码块下面就不能访问,如果静态方法定义在静态代码块下面则能访问

实例代码块(用的不多)

{java语句;}这就是实例代码块,实例代码块在创建对象的时候执行,在构造方法之前执行,可以定义多个,但可以使用类中的静态变量,实例变量,静态方法,实例方法

用途:当多个构造方法有重复的语句块时就可以使用实例代码块

小总结:

1.对于一个方法来说,方法体中的代码是有先后顺序的,自上而下

2.静态代码块1与静态代码块2也是有先后顺序的

3.静态代码块和静态变量是有先后顺序的,与静态方法没有

4.静态方法之间没有先后顺序 ,实例方法也没有

5.实例方法与实例变量也是没有先后顺序的

6.实例变量与实例变量之间是有先后顺序的,如果引用另外一个实例变量(定义在调用实例变量下面)使用this,则会使用默认值

在这里插入图片描述

答案是10 1

在这里插入图片描述

静态代码块(多个有先后顺序)–>实例代码块(多个有先后顺序)–>构造方法

this关键字

创建两个Customer对象的this内存图

在这里插入图片描述

this是一个变量,是一个引用,this中保存的是当前对象的内存地址,指向自身,this存储在堆内存当中对象的内部,this关键字只能使用在实例方法当中,不能使用在静态方法中,谁调用这个实例方法,this指向的就是谁

this什么时候不能省略?

大部分情况下是可以省略的,

在创建构造方法的时候为了提高程序的可读性,传过来的变量名与实例变量名字一样,这样就不行了,会就近原则,不会给实例变量赋值

在这里插入图片描述

在这里插入图片描述

this()的使用

this除了可以使用在实例方法当中,还可以使用在构造方法当中,通过一个构造方法1去调用构造方法2,可以实现代码复用,但this();在同一构造方法当中只能出现在代码的第一行!!!,并且只能出现一次

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无参构造方法调用全参构造方法赋值默认值1977 1 1

this小总结

在这里插入图片描述

继承

继承(extends)在现实世界当中也是存在的,例如:父亲很有钱继承给了儿子,儿子就不用努力了。。。。

子类可以继承父类的所有东西,但构造方法不能继承,私有属性也能继承但是不能直接访问(可以使用get和set方法),任何private修饰的方法都不能继承。子类继承父类之后,是将父类继承过来的方法、属性归为自己所有。

基本作用:代码可以得到复用

主要作用:因为有了继承,才有和后期的方法覆盖和多态机制

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这样就不可以子类中无法直接访问父类中private修饰的实例变量或者实例方法,但是如果父类方法中使用了private修饰的实例变量或者实例方法,子类继承过来也能使用

什么时候使用继承??

能使用is a修饰的 :Cat is a Animal Dog is a Animal

关于打印方法

System是一个类.out是一个System静态的对象属性,println()是out对象的属性

ToString方法

如果一个类当中一个方法以";"结尾,没有方法体,并且方法修饰符当中还有"native"关键字,表示底层调用的是C++的dll程序(dll)(反射getClass()方法就是)

如果已经有对象A,想创建一个与A对象一模一样的对象,可以调用clone()方法

在这里插入图片描述

源码中我们可以看出toString默认输出的是类名+对象的哈希值,对象的哈希值可以等同对象在堆内存中的地址,实际上内存地址经过"哈希算法"得到的十六进制结果,如果直接输出对象的引用则默认调用的就是toString()方法

方法的覆盖

最好将父类中的方法原封不动复制过来,进行改写,方法覆盖就是重写继承过来的方法,子类对象调用该方法的时候调用的一定是覆盖的方法

构成方法覆盖的条件

1.两个类必须要有继承关系

2.重写之后的方法与父类的方法具有相同的返回值类型,相同的方法名,参数列表一样,如果方法名与父类一样,参数列表不同的话,则构成了方法重载

在这里插入图片描述

3.访问权限不能更低,只可以更高

4.重写之后的方法不能比之前的方法抛出父类方法抛出异常的父类 什么意思???

在这里插入图片描述

这样可以,因为Exception是RuntimeException和NullPointerException的父类

这样就不可以

注意事项

1.私有方法无法覆盖

在这里插入图片描述

但是可以这样写,只是没有覆盖,因为private修饰的都没有继承过来

2.构造方法不能被继承,所以也无法被覆盖

3.方法覆盖只是针对实例方法,静态方法没有意义

方法重载与方法覆盖区别

在这里插入图片描述

多态

java支持向上转型和向上转型(两类之间必须要有继承关系)

在这里插入图片描述

向上转型(子->父)

在这里插入图片描述

猫是一种动物 这句话能说通

在这里插入图片描述

在这里插入图片描述

因为底层创建的还是Catt和Dog对象

在这里插入图片描述

编译器只知道c的类型是Animal类型,在Animal中找不到catchMouse方法,所以不行,在Animal中能找到move()方法,但底层还是Catt对象,多以调用的还是Catt对象的move()方法

这时候就要强制转型

在这里插入图片描述

向下转型(父->子)

什么时候使用向下转型?

如果你想访问的方法是子类中独特有的方法,例如上面的catchMouse()方法

在这里插入图片描述

这样不行

在这里插入图片描述

如果强制转换就会出错,只有底层创建的还是Animall的子类并且使用Animal引用才可以强制转换

instanceof运算符

向下转型有风险

在这里插入图片描述

编译器检测到a6是Animal类型,但检测到Cat与Animal之间有继承关系,不会报错,但运行会报错

怎么避免ClassCastException?? 使用instanceof运算符

1.instanceof可以在运行阶段动态判断指向对象的类型

2.( 引用 instanceof 类名);判断引用指向在堆内存中的对象是否是指定类型

在这里插入图片描述

Cat cat=new Cat();System.out.println((cat instanceof Animal);

结果是TRUE

多态在开发中的作用

当一个方法中可能传过来DDog或者Mouse的对象时,不确定哪一个,我们就可以在参数中使用Pet 类型

在这里插入图片描述

OCP(开闭原则):额外添加没问题,关闭修改原来代码,降低耦合度,提高扩展。上面的代码当中,如果再增加一个动物只需要继承Pet类,重写eat()方法就好了,不用修改Master类的feed()方法。

方法覆盖补充

没有多态机制的话,方法覆盖可有可无 ,没有多态机制,如果父类的方法无法满足子类业务需求的时候,子类完全可以定义一个全新的方法

静态方法存在方法覆盖吗??

在这里插入图片描述

结果执行的是Animal类中的doSome()方法。能这样写,但是方法覆盖与多态不能分开,多态和对象有关系,但是静态方法与对象没有关系,一般不探讨静态方法的方法覆盖,没有意义

方法覆盖的时候父类方法返回的是Animal类型的,子类重写方法的时候可以写成Animal的子类(意义不大)

super关键字

this与super

在这里插入图片描述

在这里插入图片描述

在B的构造方法第一行会默认有super();调用A类的无参构造方法

在这里插入图片描述

这样写就会报错,A写了有参构造,那么A就没有无参构造,而B类的无参构造第一行会默认有super()

默认调用父类无参构造,但发现没有就报错,所以建议把类中的无参构造方法写出来

结论:当一个构造方法既没有this()也没有super()的话,默认会有一个super(),每一个构造方法都是

this()与super()不能共存,但是有super.与this.的话也有super();

在这里插入图片描述

B的无参构造方法调用B的有参构造方法,B的有参构造方法第一行又会有super()调用A类的无参构造

无论怎么样,父类的构造方法都会执行。

套娃:

在这里插入图片描述

当创建一个C对象的时候,输出结果是 1 3 6 5 4

私有的用super.也不能调用,要是想给父类私有的属性赋值的话,需要在子类第一行使用super(实参);
在这里插入图片描述

super的内存图

在这里插入图片描述

这个CreditAccount继承Account,Account继承Object,实际上底层就就创建了CreditAccount这一个对象,这个对象当中保存了指向父类特征的super ,super(实参)作用是初始化对象父类的特征

在这里插入图片描述

shopping方法中三个指向的name结果是一样的 ,JVM图

在这里插入图片描述

子类中再写一个与父类中一样名字的属性不会报错(两者可以使用this.与super.区分所以可以区分就不会报错)

在这里插入图片描述

结果是null 与张三与null 如果子类与父类有同名属性,想访问父类的属性的话super不能省略

内存图:

在这里插入图片描述

this与super不能使用在静态方法当中

在这里插入图片描述

结果是 Cat move! Cat move! Animal move!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值