Java进阶基础知识(自己整理的笔记)

1、认识常用的数据类型

1.1 字节
  • byte一个字节,int 4个字节 ,short 2个字节 ,double 8个字节 long 8个字节
  • 字符串拼接:使用+
  • 位运算符 >>(有符号右移) >>>(无符号右移最左位用0补齐)
  • if(age)为错误的,必须为条件判断的布尔类型
  • &、|、^ 位运算符 面向整数,也可以对Boolean使用(&& 、||有短路功能)
  • 拓宽基本类型转化(自动转换)
  • 窄化基本类型转换(强制)丢失精度 布尔类型不能和数字的基本类型进行转换
  • 一元数字byte、short、char自动提升为int类型;执行一元运算符的时候(++ – ~ 左右移这些单目的运算符,还有数组的索引)称为一元数字提升
  • 一元数字提升 byte、short、char自动提升为int类型 char c = ‘A’ +c->转为了整数类型
  • 二元数字提升(多目运算) 拓宽 a + b,如果a是double\long\float,那么b也转为对应的类型,不是上边那三种的,那么都转为int
  • 标识符:flag,由java字母,java数字组成,必须有java字母开头
  • 变量名,方法名命名规则:小驼峰msFlagTrue
  • 常量(全局)全大写下划线区分
1.2 数组创建:
          int[] arr1 = new int[4];
          int[] arr2 = {}; int arr3[] = {};
		  字符数组 char[] arr4; 字符串String 不相等;
  1. 数组属于引用数据类型,数组元素存储在堆空间中,arr相当于一个栈侦,局部变量存于栈内存当中;堆空间会自动进行初始化
  2. 数组长度arr.length
  3. 数组访问内存地址:随机访问 int arr[2] > 0x1010(arr的内存首地址)+ 2*4 int有4个字节
  4. 方法,可变参数 (必须是最后一个参数)
1.3 对象数组的内存

在这里插入图片描述

public static int sum(int... n1){  n1相当于一个数组的首地址
        int result = 0;
        System.out.println(n1.length);
        for (int i : n1) {
            result += i;
        }
        return result;
    }
	public PrintStream printf(String format, Object ... args) {
        return format(format, args);
    }
	 System.out.printf("my name is %s ,age is %d%n",name,age);
  • 参数传递:基本类型是值传递,返回的是值 ,引用类型是地址值传递,返回的是地址值;
  • 方法签名 方法名+参数类型 组成 sum(int,long,double)
  • 方法重载:方法名相同,方法签名不同也就是参数个数、参数类型不同
  • 栈侦(栈内存) 随着方法的调用而创建,随着方法结束而销毁,存储了方法的局部变量信息
  • 递归调用:如果一直递归调用将一直消耗栈内存空间,内存空间溢出
  • 对象的局部变量,局部方法,都在栈空间中开辟栈内存地址,成员变量在堆空间(没有被引用时会自动被回收)
  • 引用变量是地址值传递。 方法存储
  • java程序的内存划分:
  1. PC寄存器(存储正在执行的字节码指令地址)
  2. 虚拟机栈、堆、
  3. 方法区(字段和方法信息,不包含具体的值,构造方法和普通方法 )
  4. 本地方法栈,用来调用native,c语言编写的方法

1.4 字符串

  • java.lang.String
  • 底层使用char[]数组存储字符数据。java9开始使用byte[]
  • String s = “13” 相当于String s = new String(“13”) 所以13是放在堆空间中的
  • String s = “555”
  • s = “666”
  • 栈空间的指针变量的指向发生了改变
    final关键字
  • 修饰的类为最终类,不能被继承
  • 修饰的方法不能被重写
  • 修饰变量,只能进行一次赋值;
  • 修饰成员变量:在声明中赋值,构造方法,静态代码块中,不能在创建完实例对象载进行赋值;
final static int age = 10;

常量
写法public static final int AGE = 10;

字符串常量池(SCP)

  • 在堆空间中,当遇到字符串字面量时会先去SCP查看
  • String s = “123”//字符串字面量,String s2 = new String(s)字符串字面量相同,就返回常量池中的对象value值,如果SCP中存在与字面量内容一样的字符串对象时,就返回该对象,如果没有就创建该对象,并加入SCP中,返回
    在这里插入图片描述
    intern方法
String s1 = new String("123");
String s2 = new String("123");
String s3 = s1.intern(); 有存在与s1字符串字面量一样的字符串对象时,就返回C;否则s1加入到SCP中,返回s1
String s4 = s2.intern();
String s5 = "123";

字符串常用方法

  • jdk开发文档

StringBuilder

  • 在字符串需要进行大量改动的时候(拼接、替换),如果使用String会非常消耗内存,降低程序性能,因为String在进行拼接、替换的时候都是直接在堆空间new一个新的字符串对象
StringBuilder sb = new StringBuilder();
sb.append("123").append("263");
  • 常用方法还有:append、insert、delete、replace、reverse等
  • StringBuilder并不是String的子类或者父类,和String实现了同一个接口CharSequence()
  • StringBuilder的append原理,跟动态数组原理差不多。动态数组的扩容,默认容量是16,扩容后的16*2 + 2

2、 构造方法

  • 方法名和类名一样,没有返回值,可以重载;
  • this指向当前对象引用(访问当前类中定义的成员变量,调用当前类中定义的方法也包括构造方法(构造方法中调用另外一个构造方法 this(参数))) this为隐藏方法参数
    在这里插入图片描述

在这里插入图片描述

  • 默认构造方法:public 类名(){} 作用是初始化我们的成员变量
  • package包的命名规则:公司域名倒写开头比如:com.baidu.*
  • 如何使用一个类:通过import包名.类名 方式

3 、继承

  • extend 父类引用指向子类对象
  • 类继承可以继承多个
  • Object类 顶级父类
  • 同名的成员变量
  • 方法的重写:子类的方法签名与父类的一样。 子类的方法权限必须大于父类的方法权限;子类的返回值类型必须小于父类的返回值类型

4、单例模式(饿汉式单例模式)

  • 一个类只能创建一个实例对象
  • 构造方法私有化
  • 公共的静态的方法,返回唯一的一个实例
 private static Dog instance = new Dog();
 private Dog(){}
 public static Dog getInstance(){
	 return instance;
 }

4.1、懒汉式单例模式

  • (并非线程安全)
 private static Dog instance = null;
 private Dog(){}
 public static Dog getInstance(){
	 if(instance == null){
		 instance = new Dog();
	 }
 	 return instance;
 }
  • 子类对象的内存中,依然包含父类中定义的private成员变量
  • 虽然子类对象不能直接访问,但是能通过调用父类的Get/Set方法就可以知道是存在的。

5、类

5.1 嵌套类

public class Dog{
	静态嵌套类
	static class Cat{}
	class B{}内部类
}

5.2 内部类

  • 没有被static关键字修饰的嵌套类
  • 跟实例变量、实例方法一样,内部类与外部类的实例相关联
  • 必须先创建外部类实例,再用外部类实例创建内部类实例
 Dog dog = new Dog();
 Dog.Cat cat = dog.new Cat();//创建内部类实例对象
  • 内部类不能定义除了常量之外的任何static成员
  • 堆内存划分情况:会创建一个内部类的堆内存存放成员变量,还有一个指针指向外部类;
  • 内部类可以访问外部类所有的成员,即使是private
  • 外部类也可以直接访问内部类的成员,即使是private

5.3 静态嵌套类

public class Dog{
	private static int age;
	静态嵌套类  静态内部类 在外部类被装载的时候,静态内部类并不会立刻装载
	static class Cat{
		Dog.age;  可以直接通过类名进行访问外部类中的成员(类变量、类方法),实例变量,实例方法(需要创建外部类的实例对象才能进行访问)
	}
	class B{}//内部类
}
//创建静态嵌套类的实例
Dog.Cat cat = new Dog.Cat();

什么时候用到嵌套类

  • 一个类只用到某一个类的内部的时候,可以把这个类嵌套
  • 封装新更好,程序包更简化,可读性
  • 需要经常访问一个类中的非公共成员,可以在这个类中嵌套一个类
  • 什么时候用内部类,或者静态嵌套类
  • 需要经常访问非公共的实例成员,设计成内部类,否则设计成静态嵌套类
  • 如果必须先有C实例,才能创建A实例,可以将A设计成为C的内部类
  • 内部类、静态嵌套类都可以定义实例变量、实例方法。

5.4 局部类

  1. 定义在代码块中的类(可以定义在方法中、for循环中,if语句中)
  2. 局部类中不能定义除了常量之外的任何static成员
  3. 局部类中只能访问final修饰的局部变量,或者有效final的局部变量
  4. 有效final:从java8开始,局部变量没有被第二次赋值,就认定为有效的final
  5. 可以直接访问外部类的所有的成员,即使是private修饰的

5.5 抽象类

  • 抽象方法
protected abstract void test();只能被声明,不能被实现,不能是private权限
  1. 只能是实例方法
  2. 只能定义在抽象类、接口中
  3. 抽象类不能直接被实例化,但是可以定义构造方法、静态变量、实例变量、初始化块、 嵌套类
  4. 常见的使用场景:抽取子类的公共实现到抽象父类中,要求子类必须要单独实现定义的抽象方法;
  5. 普通类与抽象类有什么区别:普通类的子类不一定要全部实现父类中的所有方法,但是抽象类的子类必须要实现所有的抽象方法。

5.6 匿名类

  • 当接口、抽象类的实现类,在整个项目中只用过一次,可以考虑使用匿名类(通俗点将就是直接new一个接口或者抽象类)
 public interface Runnable{
	 void run();
 }
 
 public static void main(String[] args){
	 new Runnable(){
		 @overide
		 void run{...}
	 };
	 //或者
	 new Runnable(){
	 		
	 }.run();
 }
  1. 匿名类不能定义除编译时常量意外的任何static成员
  2. 匿名类只有在实例相关的代码块中使用,才能直接访问外部类中的实例成员;也就是如果匿名类放在静态代码块或者静态方法中,不能够直接访问外部的实例成员。

匿名类的用途:

  • 代码块传递
  • 定义一个工具类:计算执行一段代码所用的时间
  • 过滤器
  • 回调

6、多态

  • 多态体现:
  1. 父类类型指向子类对象
  2. 调用子类重写的方法
  • 多态中类变量、成员变量的访问细节
public class Animal{
	public static void run(){}
}
public class Dog extends Animal{
	public static void run(){}
}
Animal dog = new Dog();
dog.run();调用的是Animal中的run方法,因为静态方法只看类型

instanceof

  • 判断某个类型是否属于某种类型
public class Animal{}
public class Dog extends Animal{
	Object dog = new Dog();
	if(dog instanceof Dog) //true
}

7、接口

  • 接口中可以定义抽象方法、常量(static final)可以省略、嵌套类型、java8开始可以定义:静态方法(类方法)、默认方法
  • 均是隐式public
  • 默认就是抽象方法可以省略abstract关键字
  • 不能直接实例化
  • 接口一般放行为规范
  • 当父类、接口中的方法签名一样时,那么返回值类型也必须一样。
接口
public interface Behavior{
	void eat(String name);
}
父类
public class Animal{
	public void eat(String name);
}
子类
public Dog extends Animal implements Behavior{
	@override 
	void eat(){}
}
  • 接口之间也可以继承其他接口,extends
    ##接口升级问题(增加新的功能)
  • 使用默认方法
public interface Dog{
	void eat();
	default void sleep(){
		.... 使用默认方法实现 
	}
}
  • 接口中定义的静态方法只能通过接口名调用、不能被继承
public interface Dog{
	static void eat(){}
}

排序

  • 默认升序
Arrays.sort(array);
  • 降序:
Arrays.sort(array,new Comparator<T>{
	@overide
	public T compare(T o1, T o2){
		return o1 - o2; //升序
		return o2 - o1; //降序
	}
});

8、Lambda

  • 函数式接口:只包含一个抽象方法的接口;
@FunctionalInterface //函数式接口注解
public class Dog{
	void eat();
}
//标准写法
(参数列表) -> {
	return 返回值
}//参数列表可以省略参数类型
//只有一个参数的时候,小括号可以省略
//只有一条语句的时候,可以省略大括号、return、分号
//(参数列表) -> 返回值
  • 匿名类实现的是函数式接口时,可以使用Lambda优化

  • Lambda表达式没有引入新的作用域

public class OuterClass{
	private int age = 1;
	public class InnerClass{
		private int age = 2;
		void inner(){
			//Lambda
			int v = 10;//错误写法
			Testtable t1 = v ->{
				@Override
				 publice void test(int v){
					 v;
					 age;
					 this.age;//代表OuterClass对象
					 InnerClass.this.age;
					 OuterClass.this.age;
			};	
			//匿名内部类
		     Testtable t2 = new Testable(){
				@Override
				 publice void test(int v){
					 v;
					 age;
					 this.age;//代表匿名内部类的当前对象
					 InnerClass.this.age;
					 OuterClass.this.age;
				 };
			 }
		}
	}
}

8.1 方法引用

  • 如果Lambda中的内容仅仅是调用某个方法,可以使用方法引用来简化,引用特定对象的实例方法
Public class Person{
	public void setAge(int age){
		System.out.println(age);
	}
}
static void execute(new Persion()::setAge,20){}  //new Persion()特定对象

9、枚举 enum

  • 如果一个变量的取值只可能是固定的几个值,可以考虑使用枚举
public enum  Enum {
    Spring,Summer,Fall,Winter;
}
  • 枚举由一组预定义的常量构成
  • 本质就是一个类,所有枚举类型最终都隐式继承自java.lang.Enum
  • 在定义完常量之后、枚举也可以定义成员变量、方法等
  • 枚举构造方法权限必须是无修饰符或者private
  • java会主动调用构造方法去初始化每一个常量,外界不能主动构造方法。
  public static void main(String[] args) {
      test(Enum.Spring);
    }
    public static void test(Enum season){
        switch (season){
            case Spring:
                System.out.println("春天");
                break;
            case Summer:
                System.out.println("夏天");
                break;
            case Fall:
                System.out.println("秋天");
                break;
            case Winter:
                System.out.println("冬天");
                break;
        }
    }
}

10、数字

  • 基本类型的缺陷(相比引用类型)
  • 无法表达null值
  • 当方法参数是引用类型时,基本类型无法传递
  • 不能利用面向对象的方式去操作基本类型
  • 解决方案:可以将基本类型包装成引用类型。
public class IntObject{
	private int value;//当为public时,不用提供get/set方法
	public IntObject(int value){
		this.value = value;
	}
}

10.1 包装类

  • java中已经内置了基本类型的包装类(java.lang包中)
  • 数字类型的包装类最终继承java.lang.Number

10.2 自动装箱

  • java编译器会自动调用xxxvalueOf方法,将基本类型转换为包装类
Integer i = 10;
相当于
int i = 10;
Integer.valueOf(i);

10.3 自动拆箱

  • java编译器会自动调用xxxvalue方法,将包装类转换为包基本类型
Integer i = 10;
int i2 = i;
相当于
int i2 = Integer.value(i);
  • 包装类的判等,推荐使用equals方法,不推荐使用== !=
  • Integer类型里边有缓存范围[-128,127],优先去缓存里边取出Integer对象
Integer i1 = 88;
Integer i2 = 88;
Integer i3 = 888;
Integer i4 = 888;
if(i1 == i2)//true
if(i2 == i3)//false
if(i1.equals(i2))//true
if(i3.equals(i4))//true
  • 基本类型数组和包装类数组之间是不可以自动装箱,拆箱的。只能通过遍历数组调用ValueOf方法
 public static void main(String[] args) {
     int[] arr1 = {1,2,45};
     Integer[] arr2 = new Integer[arr1.length];
     for(int i = 0; i < arr1.length; i++){
        arr2[i] =  Integer.valueOf(arr1[i]);
     }
        System.out.println(arr2);
    }

10.4 Math

  • Maht.random[0.0,1.0)

10.4 Random

Random r = new Random();
 Random random = new Random();
        int i = random.nextInt(100);//[0,99)
        System.out.println(i);
public static void main(String[] args) {
        //随机输出4位的大写字母验证码
        //A-Z-->A+[0,25]
        for (int i = 0; i <4; i++){
            char c = (char) ('A' + new Random().nextInt(26));
            System.out.print(c);
        }
    }

10.5 UUID

  • 通用唯一标识符
    System.out.println(UUID.randomUUID());生成一个128bit的随机UUID码。
    数字格式化
  long n = 45623;
        System.out.format("my age is %d%n",n);
	String.format()

10.6 字符串转数字

  • 调用包装类的valueOf\parsexxx(parseInt)
String s = "135";
        System.out.println(Integer.valueOf(s));转的为引用类型
        System.out.println(Integer.parseInt(s));转的为基本类型

10.7 数字转字符串

  • Integer.toString();

10.8 高精度计算

  • float\double存储只是小数的近拟值
  • 使用Java.math.BigDecimal来进行高精度的计算
  • 推荐使用字符串初始化BigDecimal
  • BigDecimal b = new BigDecimal(“0.7”);
  • a.add(b) -->a + b
  • a.substract(b) -->a -b
  • a.multiply(b) -->a * b
  • a.divide(b) -->a/b
  • a.setScale(3) 保留三位小数

11、日期

  • java.util.Date,日期类
Date date1 = new Date();
date1为当前中国标准时间
Date data2 = new Date(123);
data2 123+1970-01-01 00:00:02
Data data3 = new Date(System.currentTimeMills);返回的也是当前时间

11.1 SimpleDateFormat

SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");(yyyy-MM-dd)
fmt.format(Date);日期转为字符串
fmt.parse(String);字符串转为日期

11.2 Calendar

  • java.util.Calendar,日历类,是一个抽象类,不可以直接实例化
Calendar c = Calendar.getInstance();
修改日历
c.set(2018,09,12);
c.add(Calendar.MONTH,2);在这个月的基础上在加两个月

12、异常 Exception

  • 所有异常都继承自java.lang.Throwable(异常的基类)
  • RuntimeException–>Exception–>Throwable; Error–>Throwable ;除了Error、RuntimeException以外的异常称为检查型异常,不处理的话,编译不能通过
 StringBuilder s = null;
        s.append("123");
//java.lang.NullPointerException

12.1 异常处理

  • 1、try-catch
  • 2、throws
  try{
            StringBuilder s = null;
            s.append("123");
            Class<?> cls = Class.forName("com.lanren.Dog");
            Dog dog = (Dog) cls.newInstance();
            dog.test();
        }catch (Exception e){
            System.out.println("抛出了异常");
        }
        System.out.println("代码正常执行!");
  • 父类型的异常必须写在子类型的后面
Throwable中的常用方法:
StringBuilder s = null;
            s.append("123");
			
catch (Exception e){
            System.out.println(e);
			//java.lang.NullPointerException

catch (Exception e){
            System.out.println(e.getMessage());
        }	//null

catch (Exception e){
           e.printStackTrace();
        }//	java.lang.NullPointerException
	        at com.lanren.Main.main(Main.java:7)		
  • 单个catch可以捕获多个异常;catch (NullPointerException | IllegalAccessException e)

12.2 finally

  • try或catch正常执行完毕之后,一定会执行finally中的代码
  • finally代码块中经常放一些关闭、释放资源的代码。
  • try\catch,使用了return\break\continue等提前退出的 关键字,finally中的代码仍会在这些关键字之前执行

12.3 throws

  • 将异常抛给上层方法,一层层往上抛,当将异常抛给JVM的时候,程序就会终止运行。
  • 如果父类的方法没有throws异常,子类的重写父类的方法也不能有throws异常
  • 当父类的方法有throws异常,子类的重写方法可以没有throws,也可以跟父类一样的throws

12.4 throw

  • 使用throw可以抛出一个新建的异常
  • throw new Exception("");可以抛出检查和非检查型异常
  • 也可以使用return
 public void setAge(int age) throws Exception {
        if (age <= 0){
            throw new Exception("输入的年龄不合法!");
        }else{
            this.age = age;

        }

12.5 自定义异常类

  • 一般有两种,一种继承Exception,检查型异常;一种继承RuntimeExceoption,

12.6 写一个断言类

public class Assert{
   public static void test(boolean b){
       if (b){
           return;
       }
       try {
           throw new IllegalAccessException("条件不成立");
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       }
   } 
Assert.test(sum(10,20) == 30);
     Assert.test(sub(30,20) == 10);
    }
    public  static int sum(int a, int b){
        return a - b;
    }
    public static int sub(int a, int b){
        return a - b;
    }

13、正则表达式

  • 语法 作用搜索一个字符串
String regex = "正则表达式";
        String s = "1354";
        s.matches(regex);//要求完全匹配

13.1 单字符匹配

在这里插入图片描述

13.2 预定义字符

  • 以一个反斜杠开头的字符会被当做转义字符处理,因此我们的预定义字符需以两个反斜杠开头\
  • \* \& 两个反斜杠后接特殊字符也可以表示单个的特殊的字符

13.3 量词

在这里插入图片描述

13.4 Patter 、Matcher类

  • string的matches方法底层用到了Patter 、Matcher这两个类
 //通过一个正则表达式搜索一个符合条件的子列
        String regex = "\\d{3}";
        String s = "_123_456";
        findAll(regex,s);  //返回结果:123,[1,4]  456,[5,8]
		
		 //通过一个正则表达式搜索一个符合条件的子列
        String regex = "a?";
        String s = "abbcaa";
        findAll(regex,s); 
		//返回结果
		a,[0,1]
		,[1,1]
		,[2,2]
		,[3,3]
		a,[4,5]
		a,[5,6]
		,[6,6]	
public static void findAll(String regex,String input){
        if (regex == null || input ==null){
            return;
        }
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        boolean flag = false;
        while (m.find()){
            flag =true;
            System.out.format("%s,[%d,%d]%n",m.group(),m.start(),m.end());
        }
        if(!flag){
            System.out.println("bjfhe");
        }
    }
  • Matcher 贪婪、勉强、独占的区别
  • 贪婪:先对整个input字符串进行匹配,若匹配失败,则吐出最后一个字符,然后再次尝试,重复此操作,直到匹配成功
 String regex = ".*foo";
        String s = "afooadfgefgfooa";
        findAll(regex,s);
		//返回结果afooadfgefgfoo,[0,14]
  • 勉强:先吞掉input字符串的第一个字符进行匹配,若匹配失败再吞下下一个字符,然后再次尝试,重复此操作,直到匹配成功
 String regex = ".*?foo";
        String s = "afooadfgefgfooa";
        findAll(regex,s);
		返回值:afoo,[0,4]
               adfgefgfoo,[4,14]
  • 独占:吞掉整个inpu进行唯一一次的匹配
String regex = ".*+foo";
        String s = "afooadfgefgfooa";
        findAll(regex,s);
		//返回值no match

13.5 捕获组

regex = “(abc){3}”;
只有abcabcabc才匹配。因为abc是一组;

捕获组 - 反向引用

  • 可以使用反斜杠(\)+组编号(从1开始)来引用组的内容
String regex = "(\\d\\d)\\1";
        String input = "1212";
        System.out.println(input.matches(regex));//true

13.6 边界匹配符

终止符:/r回车符 /n换行符

13.7常用模式

在这里插入图片描述

常用的正则表达式

  • (https://c.runoob.com/front-end/854)

  • String里有三个方法支持正则表达式

 String s1 = "Therow row we are longling for is row 8.";
        String s2 = s1.replace("row", "line");
        String s3 = s1.replaceAll("\\brow\\b", "line");
        System.out.println(s2);
        System.out.println(s3);
		//返回结果
		Theline line we are longling for is line 8.
        Therow line we are longling for is line 8.	
String s1 = "ab12365geg78ai98kj";
        String[] split = s1.split("\\d+");
        for (String s : split) {
            System.out.println(s);
        }
		//返回结果
		ab
		geg
		ai
		kj
		
 String s1 = "aa11ab56bb66";
       String regex = "(\\w)\\1(\\d)\\2";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s1);
        while (m.find()){
            System.out.println(m.group(1)+"_"+m.group(2));
        }
		//返回结果
        a_1
        b_6
//捕获组应用:捕获字符串以某种格式找出来。
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值