Java基础学习

Java概述

Java特点

  • Java语言是面向对象的(oop)
  • Java语言是跨平台的。即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台

JDK

  • JVM(Java虚拟机)包含在JDK(java开发工具包)中
    JDK=JRE(Java运行环境)+Java的开发工具(Java开发工具包含java,javac,javadoc,javap等)
    JRE=JVM+Java的核心类库 Java使用者只需要JRE就够了,Java开发者需要JDK
    因为有了JVM,同一个Java程序在三个不同的操作系统中都可以执行。这样就实现了Java程序的跨平台性。
  • 将编写的.java文件变成对应的.class文件的过程称为编译,不同的操作系统有不同的JVM,让.class文件在不同的操作系统上跑起来的过程称为运行。
    编译的指令叫javac,运行的指令叫java,javac指令可以将.java文件生成对应的.class文件

转义字符

\t:对齐
\n:换行
\r:回车
若String中有双引号则需要用 (" 内容 ") 的方式才能将双引号打印,其他无法直接打印的字符也同理用 \

Java开发规范

Java开发注意事项和细节说明

1.Java源文件以.java为扩展名。源文件的基本组成部分是类(class),如hello类。
2.Java应用程序的执行入口是main()方法。它有固定的书写格式:
public static void main(String[] args){…}
3.Java语言严格区分大小写
4.Java方法由一条条语句构成,每个语句以“;”结束
5. 一个源文件中最多只能有一个public类。其他类的个数不限
6.如果源文件中包含一个public类,则文件名必须按该类名命名!
7.一个源文件中最多只能有一个public类。且其类名要与源文件一致;其它类的个数不限,也可以将main方法写在非public类中,然后指定运行非public类,
这样入口的方法就是非public的main方法

注释的使用

//:单行注释
/** /:多行注释
被注释的内容不会被JVM(Java虚拟机)解释执行
/** */:文本注释
注释内容可以被JDK提供的工具javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类前
javadoc.exe也是JDK文件中的程序

代码书写规范

1、类、方法的注释,要以javadoc的方式来写。
2、非javadoc的注释,往往是写给代码的维护者看的,着重告诉读者为什么这么写,如何修改,注意什么问题等。
3、选中整体,再按tab键可以实现整体的右移,用shift+tab键实现整体的左移。
4、运算符和 = 号 两边习惯各加一个空格。
5、源文件使用utf-8编码,在本机上使用GBK是因为本机控制台(dos)命令的原因。
6、行宽度不要超过80字符。
7、代码编写有次行风格和行尾风格,区别是“ { ”在行尾还是次行开头

Java API

应用程序编程接口,是Java提供的基本编程接口(Java提供的类还有相关的方法)。
中文在线文档:https://www.matools.com
Java语言提供了大量的基础类,因此Oracle公司也为这些开发者基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及类里包含的方法

路径详解

绝对路径、相对路径
相对路径:从当前目录开始定位,形成的路径
该类获取相对路径,是从src文件夹开始的,注意,是从scr文件夹开始的。
不行的话从工程名开始写
绝对路径:从顶级目录c或d等,开始定位,形成的路径
如:
在javacode开始的相对路径:
…\program1\hspjdk8\jmc.txt
绝对路径:program1\hspjdk8\jmc.txt
cd …:返回上一级
直接用绝对路径比较方便,不需要一级一级返回
cd \:返回根目录
java中文件路径可以使用正斜杠“/”和反斜杠“\”,但是反斜杠需要进行转义,写成“\”才能够被识别。
“\”和“/”的区别:
“/”和“\”具体使用中都可以达到访问路径的效果
正斜杠的话,一般在配置文件路径时,指向下一个路径只要使用一个
例如:“c:/a/1.txt”;
而反斜杠的话,在配置文件路径时,由于它本身在java中有特殊意义,作为转义符而存在,所以具体意义上的反斜杠要两个
例如:“c\a\1.txt”; 这里的第一个反斜杠是作为转义符存在的,第二个才是真正意义上的反斜杠
一般可以认为是"/“的作用等同于”\"
在java中路径一般用"/"
windows中的路径一般用""
linux、unix中的路径一般用"/"
最好用“/” 因为java是跨平台的。“\”(在java代码里应该是\)是windows环境下的路径分隔符,Linux和Unix下都是用“/”。而在windows下也能识别“/”。所以最好用“/”

变量

数据类型

基本数据类型

当把具体的数赋给byte/short/char时,
1、先判断该数是否在其范围内,如果是就可以,但是该值只能是常量,不能是变量
超出其范围如:byte的范围-128~127会变成int类型

byte,short,char 中只要有任意一个参与了运算,精度都会转成int

数值型
整数类型

存放整数
类型 占用存储空间 范围
byte[1] 1字节 -128~127(二进制存储)
short[2] 2字节 -(2¹⁵)~2¹⁵-1
int[4] 4字节 -(2³¹)~2³¹-1
long[8] 8字节 -(2⁶³)~2⁶³-1

默认值都为0

浮点(小数)类型

float[4]
double[8]

浮点型 = 符号位 + 指数位 + 尾数位
尾数部分可能丢失,造成精度损失(小数都是近似值)
运算结果是小数的,有些会有精度范围

默认值都是0.0

使用Double类进行运算时,有时会出现精度异常,这时需要用
使用BigDecimal类型来进行Double类型数据运算
创建BigDecimal类型对象时将Double类型的数据转换为字符串,通过字符串进行运算

加运算
BigDecimal sum = new BigDecimal(“0.0”)
sum = sum.add(new BigDecimal(amount + “”));
return sum.doubleValue();

乘运算
BigDecimal bigDecimalCount = new BigDecimal(this.count + “”);
BigDecimal bigDecimalPrice = new BigDecimal(this.price + “”);

BigDecimal multiReuslt = bigDecimalCount.multiply(bigDecimalPrice);

return multiReuslt.doubleValue();

doubleValue()方法是将其转换成Double类

字符型

char[2]
存放单个字符 ‘a’ 或 ‘张’

字符常量使用单引号(’ ')括起来的单个字符,如:
char c1 = ‘a’ , char c2 = ‘张’,char c3 = ‘9’;
不能用双引号" ",双引号会被认为是字符串而不是字符,会报错;

默认值:空字符,就是什么都没有(就是0对应的字符)

1.编码与中文:
Unicode/GBK: 中文2字节
UTF-8: 中文通常3字节,在拓展B区之后的是4字节
综上,中文字符在编码中占用的字节数一般是2-4个字节。

2.char在Java中的字节数:
char在Java中占用2字节。
Java编译器默认使用Unicode编码,因此2字节可以表示所有字符。

测试代码:
char a= (char) Integer.MAX_VALUE;
System.out.println((int)a);
结果输出:
65535

以上足以说明char占用的字节数是2字节。

布尔型

boolean[1]
存放 true , false
只能使用true或者false
不可以用0或非0的整数代替false,true,这点和c语言不同
boolean a = true
boolean b = false

布尔类型的默认值是false
因此定义一个布尔类型的数组如
boolean [] bar = new boolean [2];
其中 bar[0],bar[1];都为false

默认值:false

字符的本质

字符型存储到计算机中,需要将字符对应的码值找出来,比如’a’
存储:'a’→ 码值97 →二进制(110 0001)→ 存储
读取:二进制(110 0001)→ 97 → a → 显示
比特(bit):一比特相当于二进制数中的一位;
8各比特组成的二进制数代表1个字节,可以表示2的8次方个对象

字节(byte):
1个字节可以表示2的8次方个对象,2个字节可以表示2的16次方个对象,所以汉字需要2个字节,而3个字节可以表示全部的汉字

编码方式:ascll码,unicode码,utf-8,gbk… 不同的编码方式代表汉字或字母对应的码值不同也就是对应的二进制不同,不同的编码方式各有特点

引用数据类型

类(class)、接口(interface)、数组( [ ] )

变量基本使用

变量中 + 号的使用

1、当左右两边都是数值型时,则做加法运算
2、当左右两边有一方为字符串,则做拼接运算
3、字符串与数值拼接后还是字符串
System.out.println(100 + 3 + “hello”); //输出 103hello
System.out.println(“hello” + 100 + 3); //输出 hello1003

4、如果想输出两个不同的数字,在中间加个空格字符串就行了

数据类型转换

自动类型转换
当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换
数据类型按精度(容量)大小排序为
char → int → long → float → double
byte → short → int → long → float → double

(byte,short)和char之间不会相互自动转换
但是 当把具体的数赋给byte/short/char时,
1、先判断该数是否在其范围内,如果是就可以
如byte d4 = 10;//不存在默认值是int的问题,

强制转换:
上式中基本数据类型的任意两个都能进行强转
基本数据类型只有boolean无法参与强转
int a = (int) ’ b ’ ;(将字符型强转为int型)

基本数据类型转字符串:
int a = 123;
String b = a + " ";

字符串转基本数据类型:
String a = “123”;
int b = Integer.parseInt(a);
字符串里的内容要与其转化的格式对应,否则会报错

怎么把字符串转换成字符char:
a.charAt(0) 得到a字符串的第一个字符
System.out.println(a.charAt(0));

细节

// 当把具体的数赋给byte/short/char时,1、先判断该数是否在其范围内,如果是就可以
byte d4 = 10;//不存在默认值是int的问题,超出byte的范围-128~127会变成int类型
整数进行运算后会变成默认int型,再赋值给byte是不行的

想要得到1/2,1/3等
整数int型相除得到的永远是整数。
需要将2,3这些分母定义成double型或将1写成1.0

练习

练习:
1、int num1 = (int)“18”;//判断对错
2、int num2 = 18.0;
3、double num3 = 3d;
4、double num4 = 8;
5、int i = 48; char ch = i + 1;
6、byte b = 19;short s = b + 2;

答案

1、错误, 应该使用 Integer.parseInt(“18”);
2、错误,double无法赋值给int
3、对
4、对
5、int变量 无法赋值给char,
6、错误,计算过后变成int型无法赋值给short

运算符

算数运算符

% 取余(取模)
11%9 2
++ 自加
– 自减

x++:后++,先进行比较或赋值,再进行x自加
++x:前++,先进行x自加,再进行比较或赋值

关系运算符

关系运算符(比较运算符)的结果都是Boolean型,也就是要么是true,要么是false

关系运算符组成的表达式,我们称为关系表达式。如a>b

关系表达式经常用在if结构的条件中或循环结构的条件中

符号

代表关系运算符,判断是否相等。 =代表赋值
== 相等于 8
7 false
!= 不等于 8!=7 true
<

=
<=

逻辑运算符

用于连接多个条件(多个关系表达式),最终的结果也是一个Boolean值。

逻辑运算符表

在这里插入图片描述&逻辑与,相当于乘运算
|逻辑或,相当于加运算

对于&&—&,||—|,两者的计算结果相同
区别在于
&&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高
&逻辑与:不管第一个是否为false,第二个条件都要判断,效率低
开发中基本使用的是短路与&&

|| 短路或跟 | 逻辑或的区别:
||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高

!取反,false变true,true变false,
^异或,当a,b不同时为true,否则为false

赋值运算符

基本赋值运算符 = ;int a = 10;
复合赋值运算符;
+=,-=,*=,/=,%=
a += b ;等价于a = a + b
a -= b ;等价于a = a - b

赋值运算符特点:
运算顺序从右往左 int num = a + b + c;
赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值
int num = 20;int num2 = 78*34-10;
int num3 = a;

复合赋值运算符会进行类型强制转换如:
byte b = 3;
b += 2;等价于b = (byte)(b + 2);
而 b = b + 2;会报错,因为运算后是int型
b ++;等价于b = (byte)(b + 1);

三元运算符

如果条件表达式为true,运算后的结果是表达式1;
如果条件表达式为false ,运算后的结果是表达式2;

int var = a > b ? a++ : b–;
判断a > b 是否为真,若为真则执行a++,若为假则执行b–

很多情况下可以用if—else语句解决

三元运算符输出的结果为其中精度最高的
如:
trun? new Integer(1): new Double(2.0);
输出结果为1.0

运算符优先级

运算符优先级表

在这里插入图片描述1、运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如表所示,上一行运算符总优先于下一行。
2、只有单目运算符、赋值运算符是从右向左运算的。
单目运算符:(第二行,只针对一个值进行运算的运算符)

二进制

进制介绍

对于整数,有四种表示方式:
1、二进制:0,1,满2进1.以0b或者0B开头
2、十进制:0-9,满10进1
3、八进制:0-7,满8进1.以数字0表示开头
4、十六进制:0-9及A(10)-F(15),满16进1.以0x或者0X开头表示。此处的A-F不区分大小写

举例
int n1 = 0b1010;二进制 // n1= 10
int n2 = 1010;十进制 // n2= 1010
int n3 = 01010;八进制 // n3= 520
int n4 = 0x1010;十六进制 // n4= 4112

十进制转其他进制

转2
将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
转8
将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
转16
将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。

二进制转八,十六

转八:
从低位开始,将二进制数每三位一组,转成对应的八进制数即可
转十六:
从低位开始,将二进制数每四位一组,转成对应的十六进制数即可

位运算符

原码、反码、补码

1、二进制的最高位是符号位:符号位是 0时表示正数,1时表示负数
2、正数的原码、反码、补码都一样
3、负数的反码 = 它的原码符号位不变,其他位取反
4、负数的补码 = 它的反码 + 1,
负数的反码 = 负数的补码 - 1
负数的补码也等于 其原码 - 1 再取反
5、0的反码、补码都是0
6、java没有无符号数,换言之,java中的数都是有符号的
7、在计算机运算的时候,都是以补码的方式来运算的
8、当我们看运算结果的时候,要看它的原码

自己的理解

电脑自带的计算器程序员模式中的二进制是补码

计算器用补码进行二进制运算,每个补码代表一个独立的数,

标识符的命名规则和规范

标识符的命名规则

在这里插入图片描述标识符的命名规则(必须遵守)
1、由26个英文字母大小写,0-9,_或$ 组成
2、数字不可以开头如 int 3ab = 1;是错误的
3、不可以使用关键字和保留字,但能包含关键字和保留字
关键字:如class,public 等已经被Java开发者使用过的字,关键字中所有的字母都为小写
保留字:Java开发者未来可能会用到的字。现有Java版本尚未使用,但以后版本可能会作为关键字使用。
4、Java中严格区分大小写,长度无限制。
如int n = 1;int N =2;是不同的
5、标识符不能包含空格如
int a b = 90;

保留字

在这里插入图片描述

标识符的命名规范

在这里插入图片描述

控制结构

让程序有选择的执行,分支控制有三种
1、单分支
2、双分支
3、多分支

分支(if else switch)

分支控制 if-else

if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
说明:当条件表达式成立,即执行代码块1,否则执行代码块2,如果执行代码块只有一条语句,则大括号仍然可以省略

双分支

if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
说明:当条件表达式成立,即执行代码块1,否则执行代码块2,如果执行代码块只有一条语句,则大括号仍然可以省略

单分支

if(条件表达式){
执行代码块;(可以有多条语句)
}
说明:当条件表达式位true时,就会执行{ }里的代码。如果为false,就不执行。
特别说明:如果{ }中只有一条语句,则可以不用加{ }。建议加上

多分支

if(条件表达式1){
执行代码块1;
}
else if(条件表达式2){
执行代码块2;
}

else {
执行代码块n;
}

从上到下依次判断,只能有一个执行入口即当其中一个满足后就不再执行后面的,只有当前面的表达式不成立时,才会执行后面的
若所有的表达式都不成立,则执行else代码块

特别说明:
多分支可以没有else,如果所有的表达式都不成立,则一个执行入口都没有

嵌套分支

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支结构称为内层分支,外面的分支结构称为外层分支。一般不超过三层
if(){
if(){
if(){
}
else if(){
}else{
}else{
}else{
}

switch

switch语句有穿透性
switch(表达式){
case常量1:
语句块1;
break;
case常量2:
语句块2;
break;
. . .
case常量n:
语句块n;
break;
default: //default语句可以不加
default语句块;
}

case常量1:当表达式的值等于常量1,就执行语句块1
break:表示退出switch
如果和case常量1匹配,就执行语句块1,如果没有匹配,就继续匹配case常量2
如果一个都没匹配上,执行default

上面写的代码中,若case常量1与表达式相等,则执行完语句块1后就退出switch,如果没有break,则直接执行语句块2,不再判断case常量2与其是否相等。

流程图

在这里插入图片描述

细节

表达式数据类型,应与case后的常量类型一致,或是可以自动转换成可以相互比较的类型
(自动转化我暂时不会用,有需要的情况下直接使用强制转换将表达式与case中的类型转成一样的吧)
switch表达式中的返回值必须是:(byte ,short ,int ,char ,enum[枚举] ,string)
不能是float或double类型,可能是因为小数都是近似值。
但是if可以判断小数是否相等
default语句是可选的,
如果不加default语句且没有匹配任何常量值,则没有输出

switch与枚举搭配
表达式中写枚举类的对象,case语句写枚举类中定义的常量名(枚举对象)

使用时机

如果判断的具体数值不多,而且符合byte,short,int,char,enum,string这6种类型。虽然两个语句都可以使用,建议使用switch语句

其他情况:对于区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。

循环(for,while,do while)

for

for(循环变量初始化;循环条件;循环变量迭代){
循环操作(可以多语句);
}
如果循环操作只有一条,则可以省略{ }

for( ; ; );无限循环

for循环的初始循环变量初始化,每次重新开始该循环时都会进行初始化,可以不写,此时再进行该循环就不会进行初始化直接判断循环条件

流程图

在这里插入图片描述

while

while(循环条件){
循环体(语句);
循环变量迭代;
}

跟for语句没什么不同只是循环要素的位置不同

跟for一样,循环条件是要返回一个布尔值的表达式

while(true){
}
:该语句为无限循环

do while

循环变量初始化;
do{
循环体(语句);
循环变量迭代;
} while(循环条件);

也有循环四要素,只是位置不一样
先执行,再判断,也就是说,一定会至少执行一次

break

跳出控制语句-break
break用于终止某个语句块的执行一般使用在switch或者循环(for、while、do-while)中
基本语法:
{ …
break;

}

流程图

在这里插入图片描述

细节 label

在这里插入图片描述break出现在多层嵌套的语句块中时,可以通过标签表明要终止的是哪一层语句块

1、break语句可以指定退出哪层
2、label是标签名,可以设置标签名为任何标识符
3、break后面指定到哪个label就退出到哪里
4、如果没有指定label,则默认退出最近的循环体
5、尽量不要使用标签,可读性差

continue

1、continue语句用于结束本次循环,继续执行下一次循环。
2、continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,和前面标签的使用规则一样

执行流程

在这里插入图片描述

break

跳出最近的循环
for,while,是循环
if,switch,不是循环
如果if语句中有break,会跳出if外的某个循环

因为switch语句中也有break,所以switch语句的break会跳出switch

return

return使用在方法,表示跳出所在的方法,在讲解方法的时候会详细介绍,
如果return写在main主方法下,则会直接退出程序
到目前为止我还只遇见过main方法

return 的实际作用是退出并返回数据;
如果没有返回值,就是直接退出,需要与void搭配
void类型可以有return也可以没有return

数组、排序和查找

数组

数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
即:数组就是一组数据
1、数组的下标也就是[]中的数是从0开始编号的
第一个元素就是name[0];第二个元素就是name[1]
2、可以通过 数组名.length 得到数组的 长度/大小
3、访问数组中的某个元素时 用 数组名[下标值]

double[] zly = {3, 1.1 ,2}; //定义一个double类型的数组
for(int i = 0; i ❤️; i++){
System.out.println(“第”+(i+1)+“个元素的值为”+zly[i]);
} //依次输出数组中的值

如果要扩容数组,需要借助另一个新的同类数组,然后将旧数组的内容复制到新的里面;

用数组保存引用类型时,若需要修改里面的内容,可以先new 一个新的同类型对象,再将该对象指向要修改的数组,这样的话,修改该对象就等于修改数组里的哪个对象

person person = new Person();
person = n[0];

数组的使用

数据类型 数组名[] = new 数据类型 [大小]
//[]在数据类型或者数组名后面都可以

第一种动态分配方式
int a [] = new int [5];
//表示创建了一个数组,名字为a,存放5个int

第二种动态分配方式,先声明,再分配
double zly[];
声明数组。此时还没分配存储空间,是个空值
zly = new double[5];
//此时分配内存空间,可以存放数据

第三种使用方法-静态初始化
语法:数据类型 数组名 [] = {元素值,元素值…};

细节

1、数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
2、数组创建后,如果没有赋值,有默认值。
int 0,short 0,byte 0,long 0,float 0.0,double 0.0,char \u0000,boolean false,string null
3、数组的下标是从0开始的;
4、数组下标必须在指定范围内使用,否则会报错如
int [] arr = new int[5];则下标有效范围为0-4
5、数组属于引用类型,数组型数据是对象;

数组赋值机制

在这里插入图片描述基本数据类型的赋值:这个值就是具体的数据,而且相互不影响;int n1 = 2;int n2 = n1;此后如果n1或n2的值发生变化不会影响到另一个值。(值拷贝)

数组在默认情况下是引用传递(地址拷贝),赋的值是地址。
int [] arr1 = {1, 2, 3};
int [] arr2 = arr1;
arr2[0] = 10; 会连同arr1里的值一起改变

如果要使arr2里的值改变不会影响到arr1,
则要开辟新的数据空间,使用方法如下:
int [] arr2 = new int [arr1.length];
for(int i = 0;i <= arr1.length;i++)
arr2[i] = arr1[i];

排序

排序是将多个数据,依指定的顺序进行排列的过程。
排序的分类:
1、内部排序:
指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法);
2、外部排序法:
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。

查找

遍历数组中的所有元素,判断是否与想要查找的词相同

二维数组

int [] [] arr = { {1,2,3}, {4,5,6}, {7}}
此时arr.length统计的就是有几个一维数组;在这里有三个。即大{ }中有几个{ }

此时arr[0].length指的就是{1,2,3}中的元素个数,有三个

此时arr[0][1]代表二维数组中的第一个元素中的第二个元素就是2

二维数组的每个元素是一维数组,所以如果需要得到每个一维数组的值,还需要遍历

arr[i].length代表二维数组中对应下标的一维数组的长度;

int arr [][] = new int [5][];
可以先只定义二维数组中的元素个数;
arr [i] = new int [2];
然后再定义下标为i时的一维数组空间

存储机制

二维数组中的元素本质是指向一维数组的地址

细节

1、一维数组的声明方式有:
int[] x 或者 int x[]

2、二维数组的声明方式有:
int[][] x 或者 int x[][] 或者 int [] x []

3、二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度

4、声明 int [] x, y [];
其中x是一维数组,y是二维数组。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值