java笔记

*Java中的数据类型:1.byte字节型2.short短整形3.int整形4.long长整形5.flaot单精度浮点型6.double双精度浮点型
*7.char字符型8.boolean布尔型
*2、引用数据类型
*除了基本数据类型,其他全部都是引用数类型,如:String、数组等
*字节型
byte by=97;
*System.out.println((byte) (by+1));
*短整型
short sh=78;
*整形
int num=78787;
*长整型,注意: 需要早长整型末尾添加L或者l
long number=56L;
*单精度浮点型, 注意需要早长整型末尾添加F或者f
float fl=3.14F;
float fl1=3.141588888888888888888888888888888888888888881129f;
*精度丢失,System.out.println(fl1);
*双精度浮点型,java中小数默认是double类型
double db=3.1415926;
*字符型, 字符型的值使用单引号引起来,当值为整形时不需要单引号
char ch1=9;
char ch2=‘A’;
char ch3=88;
System.out.println(ch1);
System.out.println(ch3);
*布尔值类型,注意:Java中布尔值类型只有true和false两个值
boolean bool1=true;
boolean bool2=false;

  • null类型
    String str=null;
  • System.out.println(name); int a=null; 报错
    *成员常量
    final double PI=3.1415926;
    *静态常量,使用 final static 关键字修饰
    final static float price=88.88f;
    final static int HTTP_CODE=300;
    *1.常量名应该全部大写
    *2.常量名由多个字母组成应该采用下划线,HTTP_CODE
    *成员常量和静态常量再定义同时必须初始化
    *final static long bigData;
    public static void main(String[] args){
    *十进制
    int num=88;
    *八进制
    int num1=056;
    *十六进制
    int num2=0x5d8e;
    • 定义常量,使用关键字final
      final int pi=3;
    • 常量一旦被定义赋值,则不可再被修改
      *pi = 6;
    • 局部常量
      final String name;
      name = “阿建”;
      *name = “张三”;
    • Variable ‘name’ might already have been assigned to
      final long n1;
      *final static long n2 = 3L; 是错误的
      基本数据类型所占据的空间
      byte 1字节 short 2字节 char 2字节int 4字节long 8字节 float 4字节double 8
      字节数据类型转换:
      小类 型数据转换为大类型(自动转换)
      大类型转换为小类 型数据时需要强制转换(类型强转)
      转换模式:小类 型 变量名 = 小类 型 大类型
      注意:大类数据转为小类数据时可能会造成数据进度丢失和溢出
      short类型和char类型互相转化需要强制转换
      注意:两种数据类型需要彼此兼容时才可以互相转换,否则不可以转换,基本类型和引用类型不可以互相转换
      java逻辑运算符:
      *与、或、非
      && (短路与):如a&&b,全为true时才为true,否则为false
      | | (短路或):如a&&b,有一个为true或者都为true时才为true,否则为false
      ! (非) :结果相反
  • && 和 &区别:如果a为false,则不计算b(因为不论b为何值,结果都为false)
  • | | 和 | 区别 :如果a为true ,则不计算b(因为不论b为何值,结果都为true)
    关系运算符:
  • == 、 != 、 > 、 < 、 <= 、 >=
    ** 注意:关系运算符的结果为布尔值类型。
    *equals(obj)方法和的区别:
    equals方法比较的是两个对象的内容是否相等
    ”比较的是两个对象在内存存放的地址是否为同一
    Scanner :java扫描器,用户从控制台输入数据,后台java程序接收
    *next()和nextLine()方法的区别:
    *当遇到空格或者回车的时候next()方法停止读取
    *当遇到回车的时候nextLine()方法停止读取,读取整行数据
    QAQ 18:48:28
    引用类型与基本类型无法相互转换(两种数据类型必须相互兼容)
    “+”的特性:
    任何数据类型与字符串作“+”运算,都会转换成字符串。
    除运算需要有小数点及后面的数时,需改变预算的数据的数据类型
    java中只存在false与true
    关系运算符预算返回值为true/false(布尔值
    equals:使用之前需要申请对象:也可以先申请后赋值:
    scanner语句:
    Scanner scan= new scanner( System.in)
    Int q = scan.nextInt()

第一句:字符串:无法显示空格之后的内容。
第二句:字符串:可以显示至回车之前的内容。
位运算:只对整型使用
右移:除以n个2(n:右移n个位)
左移:乘以n个2
直接量/字面量:能够直接看到的值;
类型:基本类型、字符类型(flaot、string)、null类型
QAQ 18:49:10
复合语句:将多个语句组合在一起。
分支(if/else if):
多分支:
最后的else语句可要可不要
equals语句(用于比较字符内容是否相等)使用方法:“需要比较”.equals(比较的内容)
循环语句四部分:关键字、循环条件、循环体、迭代语句
while():可能一次都不执行(先判断,后执行)
du{……}while():最少执行一次(先执行,后判断)
循环嵌套层数超过三层,逻辑必定出问题
QAQ 18:49:45
遍历方法
有返回值不用写:public static void
无返必有:void
调用类里的方法需要创建类的对象。(调用非static关键字修饰的方法。)
.var
非static修饰的方法可以调用非static修饰的方法
可变参数最后将被封装成一个数组
QAQ 18:50:20
数组的创建:
静态创建数组的特点:创建数组的同时给数组元素赋值
动态创建数组的特点:创建数组时指定数组的长度,不对数组中的元素赋值
索引:下标
数组名 .for(遍历)
引用类型的数组的初始值为null
random:生成随机数
使用方法:
Random random = new random();
赋值:
Int I = random.nextInt(指定s范围)
数组:数组的四个基本特点:
1、 数组一旦被创建,它的大小将不可以在被改变。
2、 数组元素必须是相同类型的,不允许出现混合类型。
3、 数组中的元素可以是任何类型,包括基本类型与引用类型。
4、 数组属于引用类型,数组可以看成是一个对象,数组中的每一个元素相当于该对象的成员变量,因为数组本身就是对象,Java中对象是存放在堆中的,因此数组无论保存原始类型还是其他类型,数组对象本身都是在堆中。
二维数组:
java中使用 [][] 来定义二维数组,定义数组时也可同时初始化。
格式1、动态初始化
数据类型 数组名[][] = new 数据类型[m][n]
数据类型[][] 数组名 = new 数据类型[m][n]
数据类型[] 数组名[] = new 数据类型[m][n]
格式2、 静态初始化
数据类型[][] 数组名 = {{元素1,元素2…},{元素1,元素2…},{元素1,元素2…}…};
Arrays类:
**给数组赋值:**通过调用fill方法。
**对数组进行排序:**通过sort方法。
**比较数组:**通过equals方法比较数组中元素的值是否相等。
**查找数组元素:**通过binarySearch方法能对排序好的数组进行二分查找法操作。
**将数组转为字符串输出:**通过toString方法实现。

1、System.arraycopy(浅拷贝)
如:System.arraycopy(src, 1, dest, 0, 6);
2、 Arrays.copyOf(浅拷贝)
dest = Arrays.copyOf(src, 2); // Arrays.copyOf src为原数组,2为复制的位数
3、 Arrays.copyOfRange
dest = Arrays.copyOfRange(src, 1, 3);

稀疏数组介绍:当一个数组中大部分元素为0时,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组定义:
稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组。

面向对象-oop
抽象的数据类型:
所谓抽象数据类型可以理解为:将不同类型的数据的集合组成一个整体,用来描述一种新的事务。如:对象类型数据
类中可以包含:
所有对象所共有的属性/特征------------成员变量
所有对象所共有的行为-----------------方法
一个类可以创建多个对象:
同一类型所创建的对象,结构相同,数据不同
类是对象的模板,对象是类的具体的实例
面向对象的三大特征:
封装、继承、多态
定义一个类:
1、类的定义包括“成员变量”的定义和“方法”的定义,其中“成员变量”用于描述对象 共同的数据结构,“方法”则是所有对象共同的 行为。
2、Java语言中,类的成员变量的定义可以使用如下的语法:
修饰符 class 类名 {
成员变量类型 变量名;
………
}
4、 对象创建后,其成员变量可以按照默认的方式初始化,初始化对象成员变量时,其默认值的规则如下表所示:

成员变量类型默认初始值
数值类型(byte、short、int、long、float、double)0
boolean类型false
char类型/u0000
引用类型null

定义类的方法:
class 类名 {
修饰符 返回值类型 方法名(参数列表){
方法体………
}
面向对象的三大特征:

	封装、继承、多态

数组是对象:
1、在Java中,数组属于引用数据类型。
2、数组对象存储在堆中,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。
3、数组的元素可以看成数组对象的成员变量(只不过类型全部相同)
private修饰的成员变量和方法仅仅只能在本类中访问调用。
封装的意义:
1、对外提供可调用的,稳定的功能。
2、封装容易变化的,具体的细节,外界不可访问,这样封装的意义在于:
a. 降低代码出错的可能性,便于维护。
b. 当内部的实现细节改变时,只要保证对外的功能定义不变,其他的模块就不会因此而受到牵连。
封装的核心:属性私有化,行为(方法)公开化
extends关键字
1、通过extends关键字可以实现类的继承。

2、子类可以继承父类的成员变量及成员方法,同时也可以定义自己的成员变量和成员方法。
3、Java语言不支持多重继承,一个类只能继承一个父类,但是一个父类可以有多个子类。
方法的重写(Override):
1、发生在父子类中,方法名称相同,参数列表相同,方法体不同
2、重写方法被调用时,看对象的类型
3、遵循"两同两小一大"原则
多态指的是同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。
多态存在的条件:
1、 有继承关系
2、 子类重写父类的方法
3、 父类引用指向子类对象
多态的意义:
1、行为的多态(所有抽象方法都是多态的)
2、对象的多态(所有对象都是多态的)
多态的表现形式:
1、重写:根据对象的不同来表现多态
2、重载:根据参数的不同来表现多态
接口与类的区别:
1接口不能用于实例化对象
2接口没有构造方法
3接口中的所有方法必须是抽象方法
4接口不能包含成员变量如static和final
5接口不是被类继承了,而是要被类实现
6接口支持多继承,接口不能继承类,接口只能继承接口
访问接口常量:接口名.常量名
接口无法实现接口,但能继承接口同时还能多继承
成员内部类:不能定义静态的方法和变量(final除外)
定义:于类中创建一个类
作用:服务于外部类
main方法中创建内部类关键字:外部类.内部类 变量名 = 外部类对象.new 内部类
静态内部类可以通过(外部类.内部类.方法/变量)
匿名内部类:
这种形式的new语句声明一个 新的匿名类,他对一个给定的类进行扩展,或实现一个给定的接口。
示例:
New Demo01(){

};
static
被static所修饰的静态成员或方法不是方法的数据结构,而是类的数据结构(通过使用类的方法直接使用,不需要实例化对象即可使用)

final
final修饰成员变量,表示成员变量不可修改
所修饰的方法不能被重写
Static final
定义为常量,定义之时需初始化,且无法被更改。
字符串String处理:直接定义和使用String类定义;
将字符数组转为字符串:char[] ch = new char[]{‘H’,’e’,’l’,’l’,’o’}
创建建字符串
String str = new String(ch);
分配一个新字符串,该字符串包含字符数组参数的子数组中的字符:
offset参数是子数组第一个字符的索引,count参数指定子数组的长度。
复制子数组的内容;字符数组的后续修改不会影响新创建的字符串。
char[] ch1 = new char[]{'H', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd'};
String str1 = new String(ch1, 2, 8);
System.out.println(str1);
分配一个新字符串,该字符串包含来自Unicode码点数组参数子数组的字符:
offset参数是子数组第一个编码点的索引,count参数指定子数组的长度。
子数组的内容被转换为字符;int数组的后续修改不会影响新创建的字符串。
int[] arr = new int[]{65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75};
String str2 = new String(arr, 0, 5);
System.out.println(str2);
}
将字符串转为int类型的值前提是字符内容必须是纯数字,使用包装类进行转换。

String转换为int:
Integer.parselnt(str)
Integer.valueOf(str).intValue();
Int转换为String:
String s = String.valueOf(i);
String s = Integer.toString(i);
String s = “”+i;

将int类型数据转为String类型
int num1 = 56;
String str = num1 + “”;
System.out.println(str + 1);

valueOf()方法将数据的内部格式转换为可读的形式。是一种静态方法,对于所有内置的类型,在字符串被重载,以便每一种类型都能被转换成字符串。
parse()
parseXxx(String)这种形式,是指把字符串转换为数值型;

toString()可以把一个引用类型转换为String字符串类型。

concat()方法:String类的concat()方法实现了将一个字符串连接到另外一个字符串后面。语法:字符串1.concat(字符串2);

其他类型数据直接使用“+”拼接;

获取字符串长度:
使用length(),语法:字符串名.length();
1、获取字符串长度
2、将字符串转大小写
3、去除字符串两端的空白
String str = “Hello Java”;
使用length()函数获取字符串长度
System.out.println(str.length());
将字符串转为大写
System.out.println(str.toUpperCase());
将字符串转小写
System.out.println(str.toLowerCase());
String str1 = " hello ";
System.out.println(str1.length());
取出字符串两端空白
String str2 = str1.trim();
System.out.println(str2.length());
字符串截取(substring()):
* substring(int start): 从指定位置开始截取,start表示开始位置下标
* substring(int start, int end):截取指定范围内的字符串,含前不含尾
分割字符串(spilt()) String 类的 split() 方法可以按指定的分割符对目标字符串进行分割,分割后的内容存放在字符串数组中。
九、字符串的替换 1、replace() 方法 replace() 方法用于将目标字符串中的指定字符(串)替换成新的字符(串),其语法格式如下:java字符串.replace(String oldChar, String newChar)其中,oldChar 表示被替换的字符串;newChar 表示用于替换的字符串。replace() 方法会将字符串中所有 oldChar 替换成 newChar
十、字符串比较 字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。## 1、equals() 方法 equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相同的字符和长度,它返回 true,否则返回 false。
十一、1、equalsIgnoreCase() 方法 equalsIgnoreCase() 方法的作用和语法与 equals() 方法完全相同,唯一不同的是 equalsIgnoreCase() 比较时不区分大小写。当比较两个字符串时,它会认为 A-Z 和 a-z 是一样的。
2、equals()与==的比较 理解 equals() 方法和==运算符执行的是两个不同的操作是重要的。如同刚才解释的那样,equals() 方法比较字符串对象中的字符。而==运算符比较两个对象引用看它们是否引用相同的实例
1、4、compareTo() 方法 通常,仅仅知道两个字符串是否相同是不够的。对于排序应用来说,必须知道一个字符串是大于、等于还是小于另一个。一个字符串小于另一个指的是它在字典中先出现。而一个字符串大于另一个指的是它在字典中后出现。字符串(String)的 compareTo() 方法实现了这种功能。 compareTo() 方法用于按字典顺序比较两个字符串的大小,该比较是基于字符串各个字符的 Unicode 值。
2、**提示:**如果两个字符串调用 equals() 方法返回 true,那么调用 compareTo() 方法会返回 0。

十二、字符串查找
在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。## 1、根据字符查找 String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹配字符(串)的索引值。
1.1、indexOf() 方法 indexOf() 方法用于返回字符(串)在指定字符串中首次出现的索引位置,如果能找到,则返回索引值,否则返回 -1。
1.2、fromIndex 表示查找时的起始索引,如果不指定 fromIndex,则默认从指定字符串中的开始位置(即 fromIndex 默认为 0)开始查找。
1.3、lastlndexOf() 方法 lastIndexOf() 方法用于返回字符(串)在指定字符串中最后一次出现的索引位置,如果能找到则返回索引值,否则返回 -1。
十三、StringBuffer 类是可变字符串类,创建 StringBuffer 类的对象后可以随意修改字符串的内容。每个 StringBuffer 类的对象都能够存储指定容量的字符串,如果字符串的长度超过了 StringBuffer 类对象的容量,则该对象的容量会自动扩大
十四、删除字符串 StringBuffer 类提供了 deleteCharAt() 和 delete() 两个删除字符串的方法,下面详细介绍。1、deleteCharAt() 方法 deleteCharAt() 方法用于移除序列中指定位置的字符,该方法的语法格式如下:javaStringBuffer 对象.deleteCharAt(int index);deleteCharAt() 方法的作用是删除指定位置的字符,然后将剩余的内容形成一个新的字符串
十五、StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。不同的是,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。

十六、
1、静态常量 Math 类中包含 E 和 PI 两个静态常量,正如它们名字所暗示的,它们的值分别等于 e(自然对数)和 π(圆周率)。
2、生成随机数(random()和Random类) 在 Java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类。 Random 类提供了丰富的随机数生成方法,可以产生 boolean、int、long、float、byte 数组以及 double 类型的随机数,这是它与 random() 方法最大的不同之处。random() 方法只能产生 double 类型的 0~1 的随机数。 Random 类位于 java.util 包中,该类常用的有如下两个构造方法。 **Random():**该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。 **Random(long seed):**使用单个 long 类型的参数创建一个新的随机数生成器。 Random 类提供的所有方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的概率是均等的,在表 1 中列出了 Random 类中常用的方法
3、Math 类的 random() 方法没有参数,它默认会返回大于等于 0.0、小于 1.0 的 double 类型随机数,即 0<=随机数<1.0。对 random() 方法返回的数字稍加处理,即可实现产生任意范围随机数的功能。
4、BigInteger 类型的数字范围较 Integer 类型的数字范围要大得多。BigInteger 支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值。 除了基本的加、减、乘、除操作之外,BigInteger 类还封装了很多操作,像求绝对值、相反数、最大公约数以及判断是否为质数等。 要使用 BigInteger 类,首先要创建一个 BigInteger 对象。BigInteger 类提供了很多种构造方法,其中最直接的一种是参数以字符串形式代表要处理的数字。
5、igDecimal 类 BigInteger 和 BigDecimal 都能实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。一般的 float 和 double 类型数据只能用来做科学计算或工程计算,但由于在商业计算中要求数字精度比较高,所以要用到 BigDecimal 类。BigDecimal 类支持任何精度的浮点数,可以用来精确计算货币值。 BigDecimal 常用的构造方法如下。 1、BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。 2、BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。 BigDecimal 类的方法可以用来做超大浮点数的运算,像加、减、乘和除等。在所有运算中,除法运算是最复杂的,因为在除不尽的情况下,末位小数的处理方式是需要考虑的。
6、Java时间日期的处理 在 Java 中获取当前时间,可以使用 java.util.Date 类和 java.util.Calendar 类完成。其中,Date 类主要封装了系统的日期和时间的信息,Calendar 类则会根据系统的日历来解释 Date 对象。下面详细介绍这两个类的具体使用。## 1、Date 类 Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。#### 1.1、构造方法 Date 类有如下两个构造方法。 1、Date():此种形式表示分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),使用该构造方法创建的对象可 以获取本地的当前时间。 2、Date(long date):此种形式表示从 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒开始经过参数 date 指定的毫 秒数。
7、Calendar 类 Calendar 类是一个抽象类,它为特定瞬间与 YEAR、MONTH、DAY_OF—MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期) 提供了一些方法。 创建 Calendar 对象不能使用 new 关键字,因为 Calendar 类是一个抽象类,但是它提供了一个 getInstance() 方法来获得 Calendar类的对象。getInstance() 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化

十七、
1、 实现 int 和 Integer 的相互转换** 可以通过 Integer 类的构造方法将 int 装箱,通过 Integer 类的 intValue 方法将 Integer 拆箱。
2、 将字符串转换为数值类型** 在 Integer 和 Float 类中分别提供了以下两种方法: ① Integer 类(String 转 int 型)javaint parseInt(String s);s 为要转换的字符串。 ② Float 类(String 转 float 型)javafloat parseFloat(String s)**注意:**使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。

3、将整数转换为字符串** Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串
4、Object类 Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。因此,以下两个类表示的含义是一样的。

5、toString() 方法 toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。 Object 类的 toString() 方法返回“运行时类名@十六进制哈希码”格式的字符串,但很多类都重写了 Object 类的 toString() 方法,用于返回可以表述该对象信息的字符串。

6、equals() 方法 在前面学习字符串比较时,曾经介绍过两种比较方法,分别是==运算符和 equals() 方法,==运算符是比较两个引用变量是否指向同一个实例,equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。

7、getClass() 方法 getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

8、Integer类 Integer 类在对象中包装了一个基本类型 int 的值。Integer 类对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。## 1、Integer 类的构造方法 Integer 类中的构造方法有以下两个: **Integer(int value):**构造一个新分配的 Integer 对象,它表示指定的 int 值。 **Integer(String s):**构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。

Integer 类的常量 Integer 类包含以下 4 个常量。 **MAX_VALUE:**值为 231-1 的常量,它表示 int 类型能够表示的最大值。 **MIN_VALUE:**值为 -231 的常量,它表示 int 类型能够表示的最小值。 **SIZE:**用来以二进制补码形式表示 int 值的比特位数。 **TYPE:**表示基本类型 int 的 Class 实例。

10、Float 类的构造方法 Float 类中的构造方法有以下 3 个。 **Float(double value):**构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。 **Float(float value):**构造一个新分配的 Float 对象,它表示基本的 float 参数。 **Float(String s):**构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。

11、Float 类的常用常量 在 Float 类中包含了很多常量,其中较为常用的常量如下。 **MAX_VALUE:**值为 1.4E38 的常量,它表示 float 类型能够表示的最大值。 **MIN_VALUE:**值为 3.4E-45 的常量,它表示 float 类型能够表示的最小值。 **MAX_EXPONENT: **有限 float 变量可能具有的最大指数。 **MIN_EXPONENT:**标准化 float 变量可能具有的最小指数。 **MIN_NORMAL:**保存 float 类型数值的最小标准值的常量,即 2-126。 **NaN:**保存 float 类型的非数字值的常量。 **SIZE:**用来以二进制补码形式表示 float 值的比特位数。 **TYPE:**表示基本类型 float 的 Class 实例。

12、Double类 Double 类在对象中包装了一个基本类型 double 的值。Double 类对象包含一个 double 类型的字段。此外,该类还提供了多个方法,可以将 double 类型与 String 类型相互转换,同时 还提供了处理 double 类型时比较常用的常量和方法。## 1、Double 类的构造方法 Double 类中的构造方法有如下两个。 **Double(double value):**构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。 **Double(String s):**构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。

13、Number类 Number 是一个抽象类,也是一个超类(即父类)。Number 类属于 java.lang 包,所有的包装类(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象类 Number 的子类。

14、在 validateUser() 方法中,使用 for 循环遍历用户输入的用户名、密码和年龄,对其每个字符进行验证,判断其是否符合要求。在验证的过程中,分别使用了 Character 类的 isLetter() 方法、isLetterOrDigit() 方法和 isDigit() 方法。

15、Byte 类的构造方法 Byte 类提供了两个构造方法来创建 Byte 对象。
System类
System 类位于 java.lang 包,代表当前 Java 程序的运行平台,系统级的很多属性和控制方法都放置在该类的内部。由于该类的构造方法是 private 的,所以无法创建该类的对象,也就是无法实例化该类。
System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法。
System 类的成员变量
System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err。
JDK自带记录日志类
每个初学者都很熟悉在有问题的代码中使用 System.out.println 方法在控制台打印消息,来帮助观察程序运行的操作过程。如果你使用 System.out.println 方法,一旦发现问题的根源,就要将这些语句从代码中删去。如果接下来又出现了问题,就需要再插入几个调用 System.out.println 方法的语句,如此反复,增加了工作量。日志用来记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。
可以使用 setLevel 方法设置级别,例如logger.setLevel(Level.FINE);可以将 FINE 和更高级别的都记录下来。另外,还可以使用 Level.ALL 开启所有级别的记录,或者使用 Level.OFF 关闭所有级别的记录。
注意:如果将记录级别设计为 INFO 或者更低,则需要修改日志处理器的配置。默认的日志处理器不会处理低于 INFO 级别的信息。
修改日志管理器配置
可以通过编辑配置文件来修改日志系统的各种属性。在默认情况下,配置文件存在于 jre 安装目录下“jre/lib/logging.properties”。要想使用另一个配置文件,就要将 java.util.logging.config.file 特性设置为配置文件的存储位置,并用下列命令启动应用程序
Lambda 表达式
Java 中 Lambda 表达式
1、Lambda 简介
Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。
// 可计算接口
public interface Calculable {
// 计算两个int数值
int calculateInt(int a, int b);
}

	Calculable 接口只有一个方法 calculateInt,参数是两个 int 类型,返回值也是 int 类型。

// 实现加法计算Calculable对象
Calculable f1 = calculate(‘+’);
// 实现减法计算Calculable对象
Calculable f2 = calculate(‘-’);
// 调用calculateInt方法进行加法计算
System.out.println(n1 + “+” + n2 + “=” + f1.calculateInt(n1, n2));
// System.out.printf(“%d + %d = %d \n”, n1, n2, f1.calculateInt(n1, n2));
// 调用calculateInt方法进行减法计算
System.out.println(n1 + “-” + n2 + “=” + f1.calculateInt(n1, n2));
// System.out.printf(“%d - %d = %d \n”, n1, n2, f2.calculateInt(n1, n2));
}
常见的输出形式:
1、printf 主要继承了C语言中 printf 的一些特性,可以进行格式化输出。
2、print 就是一般的标准输出,但是不换行。
3、println 和 print 基本没什么差别,就是最后会换行。
箭头操作符:
->被称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:

  • 左侧:Lambda 表达式的参数列表。
  • 右侧:Lambda 表达式中所需执行的功能,用{ }包起来,即 Lambda 体。
    2、Java Lambda 表达式的优缺点
    优点:
  1. 代码简洁,开发迅速
  2. 方便函数式编程
  3. 非常容易进行并行计算
  4. Java 引入 Lambda,改善了集合操作(引入 Stream API)
    缺点:
  5. 代码可读性变差
  6. 在非并行计算中,很多计算未必有传统的 for 性能要高
  7. 不容易进行调试
    3、函数式接口
    Lambda 表达式实现的接口不是普通的接口,而是函数式接口。如果一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内),那这个接口就可以被看做是函数式接口。这种接口只能有一个方法。如果接口中声明多个抽象方法,那么 Lambda 表达式会发生编译错误。
    Lambda表达式的使用
    1、作为参数使用Lambda表达式:Lambda 表达式一种常见的用途就是作为参数传递给方法,这需要声明参数的类型声明为函数式接口类型。
    2、访问变量:Lambda 表达式可以访问所在外层作用域定义的变量,包括成员变量和局部变量。
    2.1、访问成员变量:成员变量包括实例成员变量和静态成员变量。在 Lambda 表达式中可以访问这些成员变量,此时的 Lambda 表达式与普通方法一样,可以读取成员变量,也可以修改成员变量。
    2.2、访问局部变量:对于成员变量的访问 Lambda 表达式与普通方法没有区别,但是访问局部变量时,变量必须是 final 类型的(不可改变)。
    3、方法引用
    方法引用可以理解为 Lambda 表达式的快捷写法,它比 Lambda 表达式更加的简洁,可读性更高,有很好的重用性。如果实现比较简单,复用的地方又不多,推荐使用 Lambda 表达式,否则应该使用方法引用。
    Jav异常处理:
    异常简介
    Java 中的异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类,这可以让程序具有极好的容错性且更加健壮。
    在 Java 中一个异常的产生,主要有如下三种原因:
    1、Java 内部错误发生异常,Java 虚拟机产生的异常。
    2、编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。
    3、通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。
    Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
    异常类型
    在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error。
    Throwable 类是所有异常和错误的超类,下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
    1、Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。
    2、Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。
    Exception 类型的异常处理。
    运行时异常都是 RuntimeException 类及其子类异常,如 NullPointerException、IndexOutOfBoundsException 等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。
    非运行时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常(一般情况下不自定义检查异常)。
    二、Error和Exception的异同
    Error(错误)和 Exception(异常)都是 java.lang.Throwable 类的子类,在 Java 代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。
    Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类,Exception 是程序正常运行过程中可以预料到的意外情况,并且应该被开发者捕获,进行相应的处理。Error 是指正常情况下不大可能出现的情况,绝大部分的 Error 都会导致程序处于非正常、不可恢复状态。所以不需要被开发者捕获。
    Error 错误是任何处理技术都无法恢复的情况,肯定会导致程序非正常终止。并且 Error 错误属于未检查类型,大多数发生在运行时。Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。
    常见的 Error 和 Exception:
    (1)运行时异常(RuntimeException):
    NullPropagation:空指针异常;
    ClassCastException:类型强制转换异常
    IllegalArgumentException:传递非法参数异常
    IndexOutOfBoundsException:下标越界异常
    NumberFormatException:数字格式异常
    (2)非运行时异常:
    ClassNotFoundException:找不到指定 class 的异常
    IOException:IO 操作异常
    (3)错误(Error):
    NoClassDefFoundError:找不到 class 定义异常
    StackOverflowError:深递归导致栈被耗尽而抛出的异常
    OutOfMemoryError:内存溢出异常
    三、异常处理机制
    Java 的异常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。try catch 语句用于捕获并处理异常,finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码,throw 语句用于拋出异常,throws 语句用于声明可能会出现的异常。
    异常处理的机制如下:
    1、在方法中用 try catch 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个异常。
    2、对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句拋出异常,即由上层的调用方法来处理。
    tre catch语句:
    try {
    逻辑程序块
    } catch(ExceptionType1 e) {
    处理代码块1
    } catch (ExceptionType2 e) {
    处理代码块2
    throw(e); // 再抛出这个"异常"
    } finally {
    释放资源代码块}
    在以上语法中,把可能引发异常的语句封装在 try 语句块中,用以捕获可能发生的异常。catch 后的( )里放匹配的异常类,指明 catch 语句可以处理的异常类型,发生异常时产生异常类的实例化对象。
    如果 try 语句块中发生异常,那么一个相应的异常对象就会被拋出,然后 catch 语句就会依据所拋出异常对象的类型进行捕获,并处理。处理之后,程序会跳过 try 语句块中剩余的语句,转到 catch 语句块后面的第一条语句开始执行。
    如果 try 语句块中没有异常发生,那么 try 块正常结束,后面的 catch 语句块被跳过,程序将从 catch 语句块后的第一条语句开始执行。
    多重try catch语句:
    在多个 catch 代码块的情况下,当一个 catch 代码块捕获到一个异常时,其它的 catch 代码块就不再进行匹配。
    注意:捕获的多个异常类之间存在父子关系时,捕获异常时一般先捕获子类,再捕获父类。所以子类异常必须在父类异常的前面,否则子类捕获不到。
    try catch finally语句
    try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行。例如,程序在 try 块里打开了一些物理资源(如数据库连接、网络连接和磁盘文件等),这些物理资源都必须显式回收。 Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。 所以为了确保一定能回收 try 块中打开的物理资源,异常处理机制提供了 finally 代码块。
    try {
    // 可能会发生异常的语句
    } catch(ExceptionType e) {
    // 处理异常语句
    } finally {
    // 清理代码块
    }
    对于以上格式,无论是否发生异常(除特殊情况外),finally 语句块中的代码都会被执行。此外,finally 语句也可以和 try 语句匹配使用:
    try {
    // 逻辑代码块
    } finally {
    // 清理代码块
    }
    使用 try-catch-finally 语句时需注意以下几点:
    1、异常处理语法结构中只有 try 块是必需的,也就是说,如果没有 try 块,则不能有后面的 catch 块和 finally 块;
    2、catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现;
    3、可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面;
    4、不能只有 try 块,既没有 catch 块,也没有 finally 块;
    5、多个 catch 块必须位于 try 块之后,finally 块必须位于所有的 catch 块之后。
    6、finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。

声明和抛出异常
1、throws 声明异常
当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用 throws 声明的方法表示此方法不处理异常。
returnType method_name(paramList) throws Exception 1,Exception2,…{…}
returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。

集合:集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。Java 所有的集合类都位于 java.util 包下,提供了一个表示和操作对象集合的统一构架,包含大量集合接口,以及这些接口的实现类和操作它们的算法。
集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用变量),而集合里只能保存对象(实际上只是保存对象的引用变量)。
Collection接口
Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。Collection 接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作。定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
由于 Collection 是接口,不能对其实例化,所以上述代码中使用了 Collection 接口的 ArrayList 实现类来调用 Collection 的方法。add() 方法可以向 Collection 中添加一个元素,而调用 addAll() 方法可以将指定 Collection 中的所有元素添加到另一个 Collection 中。
List集合
List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。

	List 实现了 Collection 接口,它主要有两个常用的实现类:ArrayList 类和 LinkedList 类。

1、ArrayList 类
ArrayList 类实现了可变数组的大小,存储在内的数据称为元素。它还提供了快速基于索引访问元素的方式,对尾部成员的增加和删除支持较好。使用 ArrayList 创建的集合,允许对集合中的元素进行快速的随机访问,不过,向 ArrayList 中插入与删除元素的速度相对较慢。
ArrayList 类的常用构造方法有如下两种重载形式:
1、ArrayList():构造一个初始容量为 10 的空列表。
2、ArrayList(Collection<?extends E>c):构造一个包含指定 Collection 元素的列表,这些元素是按照该 Collection 的迭代器返回它们的顺序排列的。
2、LinkedList类
LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高,但是 LinkedList 类随机访问元素的速度则相对较慢。这里的随机访问是指检索集合中特定索引位置的元素。
3、ArrayList 类和 LinkedList 类的区别
ArrayList 与 LinkedList 都是 List 接口的实现类,因此都实现了 List 的所有未实现的方法,只是实现的方式有所不同。
ArrayList 是基于动态数组数据结构的实现,访问元素速度优于 LinkedList。LinkedList 是基于链表数据结构的实现,占用的内存空间比较大,但在批量插入或删除数据时优于 ArrayList。
对于快速访问对象的需求,使用 ArrayList 实现执行效率上会比较好。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高。
不同的结构对应于不同的算法,有的考虑节省占用空间,有的考虑提高运行效率,对于程序员而言,它们就像是“熊掌”和“鱼肉”,不可兼得。高运行速度往往是以牺牲空间为代价的,而节省占用空间往往是以牺牲运行速度为代价的。
四、Set集合
Set 集合类似于一个罐子,程序可以依次把多个对象“丢进”Set 集合,而 Set 集合通常不能记住元素的添加顺序。也就是说 Set 集合中的对象不按特定的方式排序,只是简单地把对象加入集合。Set 集合中不能包含重复的对象,并且最多只允许包含一个 null 元素。
Set 实现了 Collection 接口,它主要有两个常用的实现类:HashSet 类和 TreeSet类。
1、HashSet 类
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能。
HashSet 具有以下特点:
1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
2、HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
3、集合元素值可以是 null。
HashSet 类的常用构造方法重载形式如下。
1、HashSet():构造一个新的空的 Set 集合。
2、HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。
2、TreeSet 类
TreeSet 类同时实现了 Set 接口和 SortedSet 接口。SortedSet 接口是 Set 接口的子接口,可以实现对集合进行自然排序,因此使用 TreeSet 类实现的 Set 接口默认情况下是自然排序的,这里的自然排序指的是升序排序。
TreeSet 只能对实现了 Comparable 接口的类对象进行排序,因为 Comparable 接口中有一个 compareTo(Object o) 方法用于比较两个对象的大小。例如 a.compareTo(b),如果 a 和 b 相等,则该方法返回 0;如果 a 大于 b,则该方法返回大于 0 的值;如果 a 小于 b,则该方法返回小于 0 的值。
Map集合
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。
Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。
Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。
Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。
六、遍历Map集合
Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。
1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。
2)使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好。
3)使用迭代器(Iterator)遍历。
4)通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作。
七、Collections类
Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、查找替换和复制等操作。
Collections 提供了如下方法用于对 List 集合元素进行排序。

  • void reverse(List list):对指定 List 集合元素进行逆向排序。
  • void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。
  • void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。
  • void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。
  • void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。
  • void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。
    八、Lambda表达式遍历Collection集合
    Java 8 为 Iterable 接口新增了一个 forEach(Consumer action) 默认方法,该方法所需参数的类型是一个函数式接口,而 Iterable 接口是 Collection 接口的父接口,因此 Collection 集合也可直接调用该方法。
    当程序调用 Iterable 的 forEach(Consumer action) 遍历集合元素时,程序会依次将集合元素传给 Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)。正因为 Consumer 是函数式接口,因此可以使用 Lambda 表达式来遍历集合元素。
    九、Iterator(迭代器)
    Iterator(迭代器)是一个接口,它的作用就是遍历容器的所有元素,也是 Java 集合框架的成员,但它与 Collection 和 Map 系列的集合不一样,Collection 和 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素。
    Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。Iterator 接口里定义了如下 4 个方法。
    1、boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回 true。
    2、Object next():返回集合里的下一个元素。
    3、void remove():删除集合里上一次 next 方法返回的元素。
    4、void forEachRemaining(Consumer action):这是 Java 8 为 Iterator 新增的默认方法,该方法可使用 Lambda 表达式来遍历集合元素。
    注意:Iterator 必须依附于 Collection 对象,若有一个 Iterator 对象,则必然有一个与之关联的 Collection 对象。Iterator 提供了两个方法来迭代访问 Collection 集合里的元素,并可通过 remove() 方法来删除集合中上一次 next() 方法返回的集合元素。
    当使用 Iterator 迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变,只有通过 Iterator 的 remove() 方法删除上一次 next() 方法返回的集合元素才可以。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值