java 2 se api_javaSE核心API

API:Application Programming Interface 应用程序编程接口

它是java庞大的库、是已经写好的类、方法。

java的接口和API的区别

Java接口中的方法是抽象方法,而API中的方法却是可以直接调用的。

这里说的接口有两种层面的意思:

一个面向用户,一个面向开发

1.具体的编程语言中的接口,比如:java中的接口  interface ,这个interface(接口)就是单纯指的这个interface的类是一个接口类型的类,有自己的规则,比如只能定义抽象方法什么的。

2.API接口:这个接口就是从程序上,从软件的使用层面来讲。比如任何一个web项目中,你的每一个功能的请求都是一个接口,比如:添加一个学生信息的功能就是一个用来操作数据的接口。

我们在做前后端分离的时候,前端调用后端的接口也就是API,他只需要知道调用什么接口,需要哪些参数,哪些参数必填,哪些参数有限制就可以了,他不需要知道这个接口在后端是怎么运行的,是怎么实现的。

String类

全称:java.lang.String

要点:

1.String类是用final修饰的,不能不继承。目的就是String类太常用了,防止滥用继承消耗系统性能。

2.内部其实是用char[]类型来保存的。

3.java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码。

4.String是不可变对象。 平常我们在对字符串进行拼接或改变的时候,实际上是在堆内存中重新创建了一个对象,然后将原先的引用变量指向这个新创建的对象(也就是说字符串创建的对象是不可变的,字符串引用可以重新赋值。)

String常量池

常量池:存放字符串常量和基本类型常量(public static final)

JVM为每个已加载的类型维护了一个常量池,常量池就是这个类型用到常量的一个有序集合。包括直接常量(基本类型、String)和其他类型、方法、字段的符号引用。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。java7以后字符串常量池存在于堆中。

我们创建一个字符串对象的时候 JVM会首先在字符串常量之中检查 是否之前已经创建改内容的对象 ,

如果之前有创建过该对象则重用该对象 ,如果没有则初始化,并将该字符串放入字符串常量池中。

Java常量池的作用

java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多时间。常量池其实也就是一个内存空间,不同于使用new关键字创建的对象所在的堆空间。

构造器

String str = "刘更新我是你爹";

String str = new String(byte[]  bystes,Charset cherset); //第一个参数为字节数组,第二个参数是字符类型。

String str new String(byte[] bytes,int offset,int length,Charset charset); //从offset位置开始,按lenght长度读取字节数组。

常用API

int indexOf(String ch)  //返回当前字符串第一次出现给定字符串的索引值(索引值从零开始)。 参数为字符串。找不到则返回-1

int indexOf(String ch,int fromIndex) //从指定位置开始,返回当前字符串第一次出现给定字符串的索引值。参数为字符串,起始下标。

int lastIndexOf(String ch)  //返回当前字符串最后一次出现该给定字符串的下标。

int length()  //返回当前字符串的长度,无论中英文都算1个长度。

char charAt(int index)  //获取当前字符串的 指定索引处的char值。参数为要指定的索引值。

boolean startsWith(String str)  //判断当前字符串,是否是以给定字符串开始的。

boolean endsWith(String str)  //判断当前字符串,是否是以给定字符串结束的。

String substring(int start,int end) //指定一段位置,截取当前字符串。

String toUpperCase() //将当前字符串中的英文部分全部转换为大写。

String toLowerCase()  //将当前字符串中的英文部分全部转换为小写。

String trim() //去除当前字符串两边的空白字符

String valueOf(基本类型 a)  //将给定的基本类型转换为String类型。是一组重载的静态方法,因为是静态方法使用的时候用类名String调用。

boolean equals(Object anObject) //判断当前字符串是否和给定字符串相等。一般的形式 给定字符串.equals(当前字符串)。

byte[ ] getBytes() //按照系统默认的字符集,将字符串转化为字节数组类型。

byte[ ] getBytes(String csn)  //按照给定的字符集,将字符串转化为字节数组类型。

----------支持正则表达式的方法------------

boolean matches(String regex)使用给定的正则表达式验证是否满足格式的要求

String[] splite(String regrex) 将当前字符串按 照满足正则表达式的部分进行分割删除 并返回删除后的内容

String replaceAll(String regex,String str) 将当前字符串中满足正则表达式的部分 替换为指定内容和谐脏话就是利用了replaceAll

StringBuilder类

由于String类的设计不适合频繁的修改,因为每次修改的内容如果字符串常量池中没有,则都会重新创建一个对象。对此java提供了一个用于编辑字符串内容的类StringBuilder。

其内部维护了一个可变的字符数组,不会每次都去创建新的对象,从而降低资源的开销,提高执行的效率。其提供编译字符串内容的相关方法,包括:增、删、改、插入等常见操作。

构造器

StringBuilder sb = new StringBuilder(String str);

常用API

StringBuilder append(String str)  //向当前字符串末尾添加字符串。参数为要添加的字符串

StringBuilder delete(int start,int end)  //删除指定范围的字符串。

StringBuilder replace(int start,int end,String str)  //替换指定范围的字符串。start为起始位置,end为结束位置,str为要替换的内容。

StringBuilder insert(int offset,String str)  //想当前字符串指定位置插入内容。offset为插入的位置,str为内容。

String toString()   //将当前StringBuilder类型转换为字符串类型。

还有一个StringBuffer类,他与StringBuilder方法一样执行效果也一样。区别是StringBuffer是线程安全的(他里面的方法都用了synchronized修饰),如果在多线程下操作同一字符串就要用到StringBuffer。

Object类

所有类的鼻祖,也就意味着所有的Java对象都拥有Object类的属性和方法。

当一个类没有显示的继承一个类的时候,则隐式的继承Object类,即在java编译的时候会在类的后面补上extends Object,Object的方法是非常的少的 因为它是所有类的超类。

常用API

String toString()  //java中所有的类都重写了这个方法,如StringBuilder、String。

Object类定义了toString方法,作用是将当前对象转化为一个字符串。

Object提供的方法 返回的字符串是当前对象的句柄(对象的地址信息)并没有什么实际价值所以我们通常在使用toString()时要重写该方法。

javaAPI提供的类都重写过该方法了 只有我们自己定义一个类的时候需要重写。

System.out.println(p);//默认调用重写的toString方法 即p.toString()

boolean equals(Object obj)  //在object中equals()方法中 是this == obj 除非对象等于自己否则就报错误

在java的所有的类中基本都重写了equals方法了,自己定义的类需要重写。所以我们在自己定义的类中使用equals 需要重写,从而实现比较的功能。

包装类

基本类型没有面向对象的特性,不能用多态的角度来开发。因为Object不是基本类型的超类,所以就是需要将基本类型进行包装成引用类型变相的实现基本类型的面向对象的开发。

java中提供了所有基本类型的包装类 :父类是Number的是Integer、Long、Short、Double、Float、Byte ;父类是Object的是 Character、Boolean

包装类都是final修饰的,所以不能被继承。

构造器

除了Character类以外,一般均有两个构造方法。

以Integer为例子:

Integer i = new Integer(5); //以int型变量作为参数创建Integer对象

Integer i = new Integer("5");  //以String型变量作为参数创建Integer对象

注意:boolean在使用String型参数构造对象时,仅当String值忽略大小写为true其值才为true,其他值均为false

包装类常用API

valueOf() //将基本类型转换为包装类。是一个静态的方法;所有的包装类都有这个方法。

以Integer为例子。创建一个Integer对象的时候有两种方法:

Integer i1 = new Interger(123);   或  Integer i1 = Integer.valueOf(123);

每次用new的方法去创建时,都会在堆内存中创建一个对象。而用valueOf方法创建一个对象时,如果之前创建的过相同的值则会重用之前的对象(值的范围是一个字节),从而减少内存的开销。

xxValue()//将包装类转换为数值类型。  抽象类Number 是数值型(byte/short/int/long/float/double)包装类的父类,它定义了数值型转换的方法并被的各子类所实现。

例如:

Integer i1 = Integer.valueOf(123);

float f = i1.floatValue(); //输出结果为123.0

parseXxx(String str)// 将给定的字符串,转化为对应的基本类型。是一个静态的方法。Xx为除了char类型外,Int、Short、。。。首字母大写的基本类型名称。

注意:该字符串的内容必须正确地描述了对用基本类型可以保存的值,否则会抛出异常。

例如:

String str = "123";

int d = Integer.parseInt(str); //输出就过为int 类型的123

String str = "fj";

int d = Integer.parseInt(str); //运行时抛出NumberFormatException 数字格式错误异常。

MAX_VALUE、MIN_VALUE

包装类中提供了两个常量 MAX_VALUE  MIN_VALUE 表示对应基本类型可以取到的最大值和最小值。

如int max = Integer.MAX_VALUE;  // 结果为0x7fffffff

自动拆装箱

JDK1.5推出时 推出了一个新的特性:自动拆装箱,该特性是编译器认可的 而非虚拟机

编译器在发现基本类型和引用类型相互赋值时 会自动添加代码补全它们之间的转换操作。

装箱:把基本数据类型转换成包装类,分为自动装箱和手动装箱。

拆箱:把包装类转换成基本数据类型,分为自动拆箱和手动拆箱。

例如:

手动装箱:Integer i = new Integer(123);

自动装箱:Integer i =123;

手动拆箱:double d = i.doubleValue();  //i为Integer类型

自动拆箱:double d = i;

File类

全称:java.io.File

1.File用来表示文件系统或目录的信息(名字、大小、位置、创建时间等信息)

文件系统:用一套子系统来管理硬盘上的文件

2.创建或删除文件及目录

3.访问一个目录中的子项

4.File访问不了文件里面的数据,比如访问文本文档中写的是啥

构造器

File file = new File(String pathname)

常用API

String getName()  //获取文件名字

int length()  //获取文件字节大小

boolean canRead()  //文件属性是否可读

boolean canWrite()  //文件属性是否可写

boolean isHidden()  //文件属性是否隐藏

boolean exists() //判断文件是否存在

boolean createNewFile() //创建新的文件

boolean delete() //删除指定文件(文件中无子文件或目录时)或删除目录(目录为空时)

boolean mkdir() //创建一个目录(如果创建a/b/c时若无a和b目录,则创建无效,不会报错)

boolean mkdir() //创建多级目录(创建a/b/c时若无a和b目录,则会将a和b也创建出来)

boolean isFile() //判断是否为文件

boolean isDirectory  //判断是否为目录

File[ ] listFiles() //获取目录中所有的子项

File[ ] listFiles(FileFilter pathname) //获取文件过滤器。获取过滤后的目录和文件(如获取a开头的)

文件过滤器:FileFilter类是一个含有accept()抽象方法的接口。全称java.io.FileFilter。

使用文件过滤器的时候,因为它是一个接口,所以要重写里面的accpet方法。若accept方法只调用一次,则可以用匿名内部类来创建FileFilter对象。

RandomAccessFile类

1.随机访问文件类,是专门用来读写文件数据的API。

2.其内部含有文件指针,所以基于指针我们可以对文件进行读写,并且可以通过移动指针的位置来读写任意位置。

3.创建RandomAccessFile类时有两种模式:r 只读模式,rw 读写模式。

4.在rw模式下,如果访问的文件不存在则会自动创建这个文件,若为r模式下则不会创建。

5.在硬盘上只能写二进制。

构造器

RandomAccessFile raf = new RandomAccessFile("haha.txt",rw);

常见API

int read() //从文件中读取一个字节,并且将读到的数据以int形式返回。返回值为-1则代表读到了文件末尾。

int read(byte[] data) //一次性读取给定字节数组长度的字节量,并将其内容放到数组中去。返回值为实际读取到的字节量,返回-1代表读到了文件末尾。

int readInt() //连续读取四个字节并还原int值,在 读取四字节中若发现读到末尾则抛出异常。(因为四个字节的时候可能会读到-1)RAF类提供了所有都读基本类型的方法:readInt、readDouble、redBoolean、readChar等。

void write(int d)//向文件中写入一个字节,写入的是给定的int值所对应的低八位。

void write(byte[ ] data)  //一次写入给定的字节数组大小的字节量。

void write(byte[ ] data,int index,int len)//从给定字节数组索引值为index开始、连续的写len长度的字节。 RAF类提供了所有写基本类型的方法:readInt、readDouble、redBoolean、readChar等。

注意:假设每次按照二字节去读写一个文件,如果读写的数据源字节量为2的倍数则读写正常;若不是则会出现读写问题。如每次以二字节读写7字节,则会出现读写完7个字节后,还会有1个字节被读写进去,这个字节是上一次读写二字节时末尾的那个字节。即读写abcdefg 为abcdefgf。

long getFilePointer()//获取当前文件指针的位置,返回以字节为单位的整数。

void seek(long pos)//移动文件指针到指定的位置。

IO输入输出流

IO是java标准的输入与输出,它可以让我们的java程序以标准的读写方式与外界交换数据。

流和RandomAccessFile提供的方法都是一样的,但是在底层的实现方式是不一样的。

流只有一个方向。输入或输出。

按照流是否直接与特定的地方(磁盘、内存、设备等)相连,可以分为节点流和处理流。也称低级流和高级流。低级流相当于从水管接水,而高级流相当于水龙头装上了净水器。

节点流(低级流):

只是连接程序与数据源的“管道”,负责实际读写的数据的流。只要是读写就一定是建立在低级流基础上进行的。

处理流(高级流):

不能独立存在,必须连接在其他流上(低级流高级流都行),但最后一定是连接在低级流上的。当数据"流经"当前高级流的时候,可以对数据做某些加工处理。高级流目的是为了方便简化对数据的读写操作。

根据读写的功能可以划分为两个方向:

输入:读取数据。从外界进入程序的方向。从文件里面读东西,用输入流。

输出:写出数据。从程序发送到外界的方向。向文件里面写东西,用输出流。

java.io.InputStream

InputStream类是所有字节输入流的超类,本身是一个抽象类,不能直接实例化。它规定了所有字节输入流都必须具有的读取数据的方法。

java.io.OutputStream

OutputStream是所有字节输出流的超类。本身是一个抽象类,不能直接实例化。它规定了所有字节输出流都必须具有的写数据的相关方法

文件流 FileInputStream  FileOutputStream

文件流是一对低级流,使用来读写文件数据的流。它们和RandomAccessFile都是用来读写文件数据的。但是底层的实际读写方式不同。

流是顺序读写的。使用文件流读写文件数据是不能“回头”的,因此文件流不具备对文件内容编辑操作。对写的灵活性而言没有RandomAccessFile强。但是基于流的特点,利用高级流可以轻松的对复杂的数据进行读写。RandomAccessFile利用文件指针读写,所以可以对文件任意位置进行读写操作,从而可以进行编辑操作。

java.io.FileInputStream

文件输入流。

构造器

FileInputStream fis = new FileInputStream("fos.txt");

文件输入流并没有获取文件字节数的方法。available它是告诉我们一次性至少可以读多少个字节,而不是文件的大小。所以在读文件时,创建字节数组需要我们自己给定一个值。

API用法与名字都与RandomAccessFile一样,但是底层实现不同。

java.io.FileOutputStream

文件输出流。

构造器

FileOutputStream fos = new FileOutputStream("fos.txt");

FileOutputStream fos = new FileOutputStream("fos.txt",true)   //追加模式,即在上次写的内容后面进行写操作。

API用法与名字都与RandomAccessFile一样,但是底层实现不同。

注意:用文件流的方式会在写的时候将上一次的内容进行覆盖,即相当于全部清空在写内容。而RAF是写多少就覆盖多少,没有被覆盖的依旧会保留上一次写的内容。

缓冲流 BufferedInputStream  BufferedOutputStream

缓冲流是一对高级流。使用它们读写数据的时候,无论我们的读写方式是单字节读写还是块读写都能提高效率。

使用缓冲流可以提高读写效率,但是仍然受限于硬盘。缓冲流实际上是将读写转换为块读写(内部是一次性读取8k字节的操作)从而保证读写效率。

操作的时候操作高级流的对象 ,而不是操作文件流的对象。关闭的时候也是关闭高级流,关闭高级流时 会把文件流也关闭。

流连接:使用高级流连接在其他流,最终链接在低级流上。这样的串联操作可以对低级流上的数据做一系列的加工处理操作。

java.io.BufferedInputStream

加快数据读的操作。

构造器

BufferedInputStream bis = new BufferedInputStream(InputStream fos);  //参数为InputStream这个超类类型,所以只要是它的子类都可以。//一般参数为文件流类型

BufferedInputStream = new BufferedInputStream(InputStream in, int size);  //默认缓冲区大小为8k,size可以自定义缓冲区大小。

java.io.BuffererOutputStream

加快数据写的操作。

构造器

BufferedOutputStream bos = new BufferedOutputStream(OutputStream out);

BufferedOutputStream bos = new BufferedOutputStream(OutputStream out,int size);

flush()方法

用缓冲输zhuan出流时,只有输出的字节占满缓冲区时,才会进行写操作。用flush()方法可以强制刷新进行写操作。但是频繁的调用flush会降低效率。如:在网络聊天室中,需要手动添加flush方法,因为要确保信息第一时间发送出去。

对象流 ObjectInputStream  ObjectOutputStream

对象流是一对常见的高级流。作用是可以方便我们读写任何java对象。

一个类的实例若想被对象流读写,那么必须实现可序列化接口Serializable。

java.io.Serializable

是一个接口,编译器在编译的时候会添加一个方法出来(这里作用是作用是把当前的对象转成一组字节),在源码中是不需要体现出来的。

在实现Serializable的时候是不需要重写方法的,因为它里面并没有任何的方法,此类接口称为签名接口。签名类接口实现的意义为:编译器在编译的时候会添加一个方法出来,无需体现在源码中。

在实现Serializable的是后最好添加序列化版本号serialVersUID。若不指定序列化版本号,则在当前编译时,编译器会结合当前源代码自动生成一个版本号。只要对当前类的源码做出改动,版本号就会变化,而版本号关系着反序列化的结果。即当对象输入流在读取一个对象进行反序列化时(将字节转化为实例对象,且被读取的对象是通过对象输出流转化成的字节)会检查该对象与当前类的版本号是否是一致的,不一致则会派出序列号版本不同的异常。

在类的一个属性中添加transient修饰 会使在反序列化时忽略此成员变量,忽略不必要的属性可以减少资源开销。

java.io.ObjectInputStream

对象输入流。可以将一组字节读入,并按照其表示的结构转化为对应的对象。

读取的字节必须是通过对象输出流将一个对象转换的字节。

构造器

ObjectInputStream ops = new ObjectInputStream(InputStream in); //一般参数为文件流类型

用 final void readObject(object p) 方法来读取一个对象,参数为引用类型。

/*读取Person类*/

public classObjectInputStreamDemo{public static void main(String[] args) throwsIOException, ClassNotFoundException {

FileInputStream fis = new FileInputStream("fis.obj");

ObjectInputStream ois = new ObjectInputstream(fis);

Person p = (Person)ois.readObject(); //强转成Person类型

system.out.println(p);

ois.close();

}

java.io.ObjectOutputStream

对象输出流。可以将给定的java对象按照其结构转化为一组字节后写出。

构造器

ObjectOutputStream oos = new ObjectOutputStream(OutputStream out)  //参数一般为文件流类型

用final void writeObject(Object obj) 来写入一个类。参数为对象。该方法要求写出的对象所属类必须实现Serializable接口,否则会报NotSerializableExpection异常

/*将Person类写入文件中*/

public classObejctOutputStreamDemo{public static void main(String[] args) throwsIOException{

Person p = new Person("更新","22","我儿子");

FileOutputStream fos = new FileOutputStream("fos.obj");

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(p);

Sysotem.out.println("写入完毕");

oos.close();

}

}

字符流

java中流可以分为高级流和低级流。还可以按照读写的数据单位划分为字节流、字符流。

由与读写文本数据是一件非常频发的操作,所以java专门设计了字符流。

字符流是以字符为单位读写数据的。但是底层实际上还是读写字节(因为计算机中一切皆为二进制)

字节与字符之间的转换工作字符流自行完成了。对此也需要注意到字符流的局限性,仅适合读写文本数据(不局限于文本文档)

java.io.Reader

Reader是抽象类。是所有字符输入流的超类,规定了字符流读字符的相关方法。

常用API:

int read() //读取一个字符,返回的int值是"低十六"位有效(因为char值为2字节),虽然返回值是int,但是他读取的是字符所以可以通过强转为char类型读出来。

int read(char[ ] chs) //从该流中读取一个给定字符数组的length个字符并存入该数组。返回值为实际读取到的字节量

java.io.Writer

Writer是抽象类。是所有字符输出流的超类,规定了字符流写字符的相关方法。

常用API:

void write(int c)//写出一个字符,写出的是给定的int值的“低十六”位的字符。

void write(char[ ] chs) //将给定的字符数组中的所有字符写出。

void write(char[ ] chs,int offset,int len) //将给定的字符数组从offset处开始,连续的写出len个字符。

void write(String str) //将给定的字符串写出。

转换流 InputStreamReader  OutputStreamWriter

转换流是连接字节流和字符流的桥梁。用于字节流和字符流之间的转换,它就相当于一个转换线,将更高级的字符流和字节流进行连接。

转换流是唯一的一对可以连接在字节流上的字符流。在使用字符流读写数据时,作为流连接重要的一环存在。

实际应用时不会直接操作这两个流,因为其上还会连接其他高级的字符流。

java.io.InputStreamReader

字符输入流。

构造器

InputStreamReader osw = new InputStreamReader(InputStream in);//参数一般为文件流类型

InputStreamReader osw = new InputStreamReader(InputStream in,String charSet);//charSet为读出的文本数据的字符集不指定默认为当前系统的字符集。

int read() //字符流定义的该方法是读取一个字符,实际从数据源读取几个字符去解决于字符集。但是当读取到该字符后在java内部都是以Unicode编码保存的,就变为固定的2字节的char了。

没有读字符串的方法。因为不一定一个句号就是一个字符串,只能一个一个字的读。

java.io.OutputStreamWriter

字符输出流。

构造器

OutputStreamWriter osw = new OutputStreamWriter(OutputStream out);//参数一般为文件流类型

OutputStreamWriter osw = new OutputStreamWriter(OutputStream out,String charSet);//charSet为写出的文本数据的字符集不指定默认为当前系统的字符集。

void write(String str)  //像文件中写入字符串

缓冲字符流 PrintWriter  BufferedReader

加入字符缓冲流,增强读取功能,新增方法readLine() 更高效的读取。

PrintWriter

缓冲字符输出流。具有自动换行刷新的缓冲字符输出流,写出一个字符串就会自动换行。

注:java.io.BufferedWriter是缓冲字符输出流。而PrintWriter的内部是连接BufferedWriter来完成缓冲工作。因为PrintWriter在其基础上还支持自动的换行刷新操作所以更为常用。

构造器

缓冲字符输出流提供了直接写文件的构造方法。使用时看起来很像低级流,其内部连接了BufferedWriter、OutputStream、FileOutputStream。

直接进行构造的方法:

PrintWriter pw = new PrintWriter(String path/File file)  //参数为文件路径或名称。

PrintWriter pw = new PrintWriter(String path/File file,String csn)  //csn为字符集。其内部还是交给了OutputStream来处理。

流连接时的构造方法:

PrintWriter pw = new PrintWriter(Writer out)  //out为字符输出流类型,一般为转换输出流。不会自动进行flush操作。

PrintWriter pw = new PrintWriter(Writer out,boolean autoFlush)  //autoFlush表示创建的PrintWriter是否为自动行刷新模式,即每写出一行时,都会自动进行flush操作。

void println(String str)  //像文件中按行写入字符串。

java.io.BufferedReader

缓冲字符输入流。可以按行读取字符串。

构造器

BufferedReader br = new BufferedReader(Reader in)  //参数字符流类型。一般为转换输入流。

String readLine()//连续读取若干个字符串,知道读到换行符,就将独到的字符以字符串的形式返回。且返回的字符串不含由最后的换行符,当返回值为null时,表示读到了末尾。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值