【Java SE基础 二】Java基本语法

我们需要了解一些基础的Java 语法来进行java的学习,这里我做了一些小小的总结,具体涉及以下内容:标识符和关键字,数据类型(基本数据类型、基本数据类型的转换、引用数据类型),常量和变量,运算符,语句,方法。这部分是Java后续的基石,可以这么理解:标识符和关键字用来给接下来的各种内容起名字,数据类型用于给变量和常量设置类型,变量需要进行运算有各种运算符,这些运算可以归结为语句,循环或者判断,而语句放在方法里执行,这样我们一个整体语法基石就构建完成了。
在这里插入图片描述
是通过看视频,看书了解的,现在拿出来与大家分享,这部分的学习大概从2015年10月开始。首发于CSDN,于2021年1月21日二次更新和补充。

标识符和关键字

标识符和关键字就是我们在Java代码中填写的一些命名,只不过标识符是我们自己能定义的,关键字则有其特殊含义。

标识符

标识符就是一切可以起名字的地方:包名、类名、接口名、方法名,常量名、变量名等,标识符有以下的命名规则

  1. 标识符由字母、数字、_(下划线)、$符 组成
  2. 不能以数字开头
  3. 不允许单独使用下划线作为分隔符(Java9)
  4. 不能用Java中的保留字(关键字)
  5. 对大小写敏感,长度没有限制

标识符采用有意义的简单命名,一般我们用一个英文单词去命名,并且遵循如下命名规范(驼峰命名法):

  • 包名:包名一般采用全小写的格式
  • 类名和接口名:每个单词的首字母大写,其余为小写。(大驼峰即帕斯卡命名法)
  • 方法名和变量名:第二个单词起的首字母为大写,其余全为小写。(小驼峰)
  • 常量名:基本数据类型的常量名使用全部大写字母,字与字之间用下划线分隔。

以上就是一些简单的标识符命名规范。

关键字

什么是关键字呢?关键字就是在java语言中赋予特殊含义的单词,它有两个特点:1.组成的关键字的单词全是小写,2.常见的代码编辑器中,对关键字都有特殊的颜色标记,共计48个关键字:

  • 用于包的关键字[2]import(导入这个类所存在的包);package(定义包的关键字,将有关类放在一个包中)
  • 定义类、接口、抽象类[3]class(声明一个类);interface(声明一个接口);abstract(表明类或者成员方法具有抽象属性)
  • 用于建立类与类之间关系[2]implements(implements 表明一个类实现了给定的接口类);extends (表明一个类型是另一个类型的子类型,常见的类型有类和接口)
  • 用于定义访问权限修饰符[4],Java分别定义了四种访问级别:private、protected(当前包不一定为子类以及跨包子类均可)、default(默认访问限制)、public在这里插入图片描述
  • 用于定义建立实例及引用实例、判断实例[4]new(用来创建新的实例对象),this(指向当前实例对象的引用),super(表明当前对象的父类型的引用或者父类型的构造方法),instanceof(用来测试一个对象是否是指定类型的实例对象)
  • 用于定义类、函数、变量修饰符【4】final(终结器,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量); static(表示具有静态属性);synchronized(线程同步,修饰一段代码表示多个线程都能同步执行) ,volatile (原子操作,表明两个或者多个变量必须同步地发生变化),native(本地用来声明一个方法是由计算机相关语言实现的(如C/C++语言等))
  • 用于异常处理【5】try(尝试一个可能抛出异常的程序块);catch(用在异常处理中,用来捕捉异常);finally(用于异常处理情况,用来声明一个基本肯定会被执行到的语句块(有没有异常都执行));throw(通常用在方法体中,并且抛出一个异常对象,程序在执行到throw语句时立即停止,它后面的语句都不执行);throws(如果一个方法可以引发异常,本身不对异常进行处理,将异常抛给调用者使程序可以继续执行下去)
  • 程序控制语句【11】break(跳出循环); continue (继续);return (返回);do (运行);while(循环);if (如果);else(反之);for (循环);switch (开关);case (返回开关里的结果); default (返回默认结果)
  • 数据类型关键字【11】boolean(布尔型);byte( 字节型);char (字符型);double (双精度);float( 浮点);int (整型);long (长整型);short (短整型);string(字符串);enum(枚举类型);strictfp(strict float point 精确浮点)。
  • 用于特殊用途【2】assert (断言,用来进行程序调试); transient(表示一个成员变量不是该对象序列化的一部分)

除了48个关键字之外,还有2个保留关键字

  • 保留关键字【2】:goto(跳转到)、const(常量)。(现在没用以后可能用到作为关键字)

剩下的都是保留字,Java保留字是指现有Java版本尚未使用,但以后版本可能会作为关键字使用:

  • 特殊直接量【3】true(正确);false(错误);null(空值)
  • 其它保留字【9】: byValue, cast,future, generic, inner,operator, outer, rest, var

也就是说,Java中48个关键字、2个保留关键字以及12个保留字,都不能作为标识符来使用,这点需要注意,其中除了9个其它关键字,以上关键字与保留关键字以及特殊直接量会编译错误,而9个其它关键字不会,但仍然不建议使用,防止以后作为关键字使用导致的历史代码无法正确运行。

java的关键字与保留字

还有要注意true,false,null,不是java的关键字,但是你不能把它们作为java标识符用。

标识符和关键字了解后可以看一个简单示例:
在这里插入图片描述

Java数据类型

在上文保留字中我们提到了Java涉及的一些数据类型,这些类型在常量和变量中的定义中也会用到,我们先来梳理下:
在这里插入图片描述
Java 语言是一种强类型语言。通俗点说,在 Java 中存储的数据都是有类型的,而且必须在编译时就确定其类型。 Java 中有两类数据类型:

  • 基本数据类型变量:存的是数据本身,基本数据类型变量里存储的是直接放在抽屉里的东西
  • 引用类型变量:存的是保存数据的空间地址,引用数据类型变量里存储的是这个抽屉的钥匙,钥匙和抽屉一一对应

需要注意的是String 是一种常见的引用数据类型,用来表示字符串。

基本数据类型

我们知道基本数据类型有8种,name接下来对基本数据类型涉及内容及转换过程做详细介绍。

基本数据类型特性

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。Java中所有的数据类型在所有的操作系统上占的位数都一样,所以可以跨平台。 各个基本类型如下所示:

  • byte【1字节】:byte 数据类型是8位、有符号的,以二进制补码表示的整数;最小值是 -128(-2^7);最大值是 127(2^7-1);默认值是 0;byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;例子:byte a = 100,byte b = -50。
  • short【2字节】:short 数据类型是 16 位、有符号的以二进制补码表示的整数最小值是 -32768(-2^15);最大值是 32767(2^15 - 1);Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;默认值是 0;例子:short s = 1000,short r = -20000。
  • int【4字节】:int 数据类型是32位、有符号的以二进制补码表示的整数;最小值是 -2,147,483,648(-2^31);最大值是 2,147,483,647(2^31 - 1);一般地整型变量默认为 int 类型;默认值是 0 ;例子:int a = 100000, int b = -200000。
  • long【8字节】:long 数据类型是 64 位、有符号的以二进制补码表示的整数;最小值是 -9,223,372,036,854,775,808(-2^63);最大值是 9,223,372,036,854,775,807(2^63 -1);这种类型主要使用在需要比较大整数的系统上;默认值是 0L;例子: long a = 100000L,Long b = -200000L。"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。
  • float【4字节】:float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;float 在储存大型浮点数组的时候可节省内存空间;默认值是 0.0f;浮点数不能用来表示精确的值,如货币;例子:float f1 = 234.5f。
  • double【8字节】:double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;浮点数的默认类型为double类型;double类型同样不能表示精确的值,如货币;默认值是 0.0d;例子:double d1 = 123.4。
  • boolean【1字节】:boolean数据类型表示一位的信息;只有两个取值:true 和 false;这种类型只作为一种标志来记录 true/false 情况;默认值是 false;例子:boolean one = true。
  • char【2字节】:char类型是一个单一的 16 位 Unicode 字符;最小值是 \u0000(即为 0);最大值是 \uffff(即为65、535);char 数据类型可以储存任何字符;例子:char letter = ‘A’;。

了解了8大基本数据类型和注意事项后我们再看看它们是怎么相互转换的。

基本数据类型转换

基本数据类型之间满足以下条件可以实现互相转换:

  1. 布尔类型和其他类型不可以互相转换
  2. byte,short,char不能互相转换,在做运算之前会自动转换为int类型。
  3. 容量小的类型可以自动转换为容量大的数据类型【byte,short,char—》int—》long—》float—》double】
    • 特殊情况: Java语言整型默认为int型,声明long型常量时候需要后边加’L’或者‘l’,long l=1232323L,当赋值给long变量没有加‘ l ’或‘ L ’ ,仍旧默认成int类型。如果赋值的时候没有超出int表述范围没关系,即使超出了int的表述范围,也不用担心,不会报错但会导致数值计算错误
  4. 容量大的转换为容量小的需要强制转化,可能会丢失精度,特殊情况:
    1. 赋值的时候只要int类型的数没有超出(byte,short,char)的表述范围,可以直接byte a=23,
    2. Java语言默认浮点型常量为double型,如果要声明一个常量float型,则需要在后边加f或者F, 直接转不过去,直接转会导致溢出现象float l=1232323.45F
  5. 多种混合计算时,自动将所有数据类型转换为容量最大的一种数据类型。

以下为一些转换的代码示例:

public static void main(String[] args) {
       boolean b=true;
       System.out.println(b);
       byte b1=67;    //byte类型直接后边赋值即可,int类型可以自动赋值到byte上,只要不超过127,但是float f=0.1就不行,必须加f,虽然没超出范围。总结起来就是整型之间虽然不是int但是只要没超过int范围就没必要加强制转换或者是末尾加l,但是浮点型的不行,一定得加强制转换或者是末尾加f。
       byte b2=99;
       byte b3= (byte)(b1+b2);   //在计算之前(byte,short,char会自动转换为int,所以需要强制转换为byte)
       System.out.println(b3);    //如果直接超过127 ,不会有溢出错误,直接砍掉多余位数
       char c1='t';
       int b4=b3+c1;
       System.out.println(b4);    //char,byte,short不可以互相转,但是可以进行混合运算
       
       int i1=123;
       int i2=456;
       double d1=(i1+i2)*1.2; //系统将会自动把int型的转为double型的计算,因为浮点型的1.2是默认double型的,混合运算中又要取最大范围
       System.out.println(d1); 
       
       float f1=(float)d1;   //因为d1是double型的,所以要强制转换为float型的。
       System.out.println(f1); 
       double d2=1e200;
       float f2=(float)d2;
       System.out.println(f2); //因为d2超出了float能承受的范围,所以会溢出
       
       float f3=12.344343f;    //后边必须加f
       long l1=1234l;
       long l2=3455l;
       float f4=f3+l1+l2;
       System.out.println(f4);  //混合运算自动都变为float型的
       
       long l3=(long)f4;
       System.out.println(l3);    //强行把浮点数类型的转化为整型的会导致没有小数位,不是四舍五入,而是彻底没有小数部分。
       
	}

转换过程预期和纠错:


public static void main(String[] args) {
	    int i=1,j=12;      //对i,j赋初始值
	    float f1=(float)0.1;  //0.1f与这里的写法是有区别的,0.1f表示内存分配就分配了4个字节,而这种写法意思是8字节的double类型然后强制转换
	    float f2=123;   //123默认是int类型的,可以自动转为float
	    long l1 = 12345678,l2=8888888888L;   //l1这里没有超出int的范围,所以不用加l,而l2显然超过啦,所以必须加l
	    double d1 = 2e20,d2=124;    //int类型自动转为double
	    byte b1 = 1,b2 = 2,b3 = 127;  //只要没超过int的表述范围,赋值不需要加强制转化
	    j = j+10;
	    i = i/10; 
	    i=(int)(i*0.1);   //这里虽然与上边相同的计算结果,过程不一样,首先计算后为double,必须加强制转化
	    System.out.println(i);  //i是int型,10是int型,所以计算结果为0,也必须是int型
	    i = (int)(i*0.1);  //i是int型的,乘0.1后变为double型,必须强制转化为int型
	    char c1='a',c2=125;
	    byte b = (byte)(b1-b2);
	    char c = (char)(c1+c2-1);    //混合运算,统统转为int,运算结束后再转为char型的
	    float f3 = f1+f2;
	    float f4 = (float)(f1+f2*0.1);
	    double d = d1*i+j;
	    float f = (float)(d1*5+d2);
		}

引用数据类型

除了基本数据类型,都是引用类型,一般包含包含类、接口和数组,其实String类型也可以当作一种引用类型。引用类型占两块内存:一块为空值,定义一个引用类型;另一块为引用类型new出来的放堆里边进行动态内存分配,不用的时候就会被垃圾回收机制回收

  • 栈内存:存放堆内存中的真实对象地址
  • 堆内存:存放new出来的动态对象,不用的时候就会被垃圾回收机制回收

关于引用类型如何使用在后边的blog会提到,关于Java的内存结构也会在后边提到,这里做简单记忆。

常量和变量

了解了数据类型和语法后,我们先来了解下Java里的常量和变量分别指什么。

变量

变量指的是值会改变的量,在Java中我们通过三个元素来描述变量:变量类型,变量名以及变量值。按照不同的角度,变量可以做如下的分类:

  1. 局部变量和成员变量:局部变量表示在方法体里面声明的变量,成员变量表示类体里面,方法体外边声明的变量,注意方法的参数属于局部变量,成员变量会默认初始化,而局部变量不会成员变量并不能随意在各个方法中使用,如果想直接使用,成员变量与方法之前必须加static关键字,此时该成员变量或成员方法即相当于全局的概念,如果不加static,那么必须先new该类出一个实例,然后再调用变量和方法
  2. 按照方法的作用域划分:凡是在大括号里声明的变量,出了大括号就没人认识它了,在这个大括号里边的都认识它。
  3. 按照数据类型划分变量,不同的变量类型来划分。

变量还有一些特征和使用规范:

  1. Java 中的变量需要先声明后使用,变量使用时,可以声明变量的同时进行初始化,也可以先声明后赋值
  2. 命名规范:虽然语法中没有提示错误,但在实际开发中,变量名不建议使用中文,容易产生安全隐患,譬如后期跨平台操作时出现乱码等等
  3. 赋值规范:变量中每次只能赋一个值,但可以修改多次,main 方法中定义的变量必须先赋值,然后才能输出

以上就是变量的分类和使用规范了。

public class testvar {
	//int j; 
	static int j;                // 成员变量,可以作用于整个类

	public void m() {     // 虽然在main方法里也有i,但没关系,作用域都是本方法
		int i = 0;
		System.out.println(i);
	}

	public static void main(String[] args) {
		int i=0 ;          
		int t=i+5;    //这里局部变量i必须先被赋初始值,否则不能编译。
		int k=j+5;      //成员变量可以不用赋初始值,系统会默认分配
		System.out.println(k);
		//testvar tt=new testvar();    //非静态方法,需要先new出一个对象来,然后再调用
		System.out.println(i);
		//System.out.println(tt.j);     
		System.out.println(j);     //只有成员变量定义为static,才可以直接打印
		System.out.println("tianmaolin" + 123); // 这个属于常量的概念,直接可以打印相对应的常量值,不用定义声明赋值。

		boolean b = false;
		if (b) {
			int c = 0;
			System.out.println("b is true");
		}
		
		// System.out.println(c); //打印不出来,出了c的作用域了,根本就找不到c
		long longNum1 = 8888888888888L;

常量

所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变,常见常量类型有如下几种:

  1. 整形常量:int ,long
  2. 浮点型常量:float,double
  3. 字符常量(char):‘a’
  4. 字符串常量(string):“abcdefg”
  5. 逻辑常量(boolean):布尔类型,true ,false

常量还可以表示值不可以改变的变量,例如final关键字:final 常量名=值:final double PI=3.14。常量名一般使用大写字符。程序中使用常量可以提高代码的可维护性。例如,在项目开发时,我们需要指定用户的性别,此时可以定义一个常量 SEX,赋值为 “男”,在需要指定用户性别的地方直接调用此常量即可,避免了由于用户的不规范赋值导致程序出错的情况

运算符

按照运算符分类,Java支持如下的运算符类别:算数运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、字符串连接运算符

  • 算数运算符【7】:算术运算符包括通常的加(+)、减(-)、乘(*)、除(/)、取模(%),完成整数型和浮点型数据的算术运算;Java允许对浮点数进行取模操作。例如,3%2 的结果是 1, 15.2%5 的结果是 0.2。取模操作还可以用于负数,结果的符号与第一个操作数的符号相同,例如,5%-3 的结果是 2;算术运算符还有 自增(++)、自减(–)两种,分别称为加1和减1运算符。这两种运算符有前缀形式和后缀形式,含义有所不同。例如,i++ 和 ++i 的执行顺序是不一样的,i++ 在 i 使用之后再 +1,++i 在 i 使用之前先 +1。i-- 和 --i 的情况于此类似;2,-5%3 的结果是-2
  • 位运算符【7】:位运算符用来对二进制位进行操作,包括按位取反(~)、按位与(&)、按位或(|)、异或(^)【相同为0相异为1】、右移(>>)、左移(<<)和无符号右移(>>>)。位运算符只能对整数型和字符型数据进行操作
  • 关系运算符【7】:关系运算符用来比较两个值,包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)和不等于(!=)、instaceof(检查是否是类的对象)。关系运算符都是二元运算符,也就是每个运算符都带有两个操作数,运算的结果是一个逻辑值。Java允许“==”和“!=”两种运算符用于任何数据类型。例如,既可以判断两个数的值是否相等,也可以判断对象或数组的实例是否相等。判断实例时比较的是两个对象在内存中的引用地址是否相等
  • 逻辑运算符【5】:逻辑运算符包括逻辑与(&)、逻辑与【短路版】(&&)、逻辑或(|)、逻辑或【短路版】(||)和逻辑非(!)。前两个是二元运算符,后一个是一元运算符。Java对逻辑与和逻辑或提供“短路”功能,也就是在进行运算时,先计算运算符左侧的表达式的值,如果使用该值能得到整个表达式的值,则跳过运算符右侧表达式的计算,否则计算运算符右侧表达式,并得到整个表达式的值
  • 条件运算符【1】:也称为 “三元运算符”或“三目运算符”。语法形式( ? : ):布尔表达式 ? 表达式1 :表达式2。运算过程:如果布尔表达式的值为 true ,则返回 表达式1的值,否则返回 表达式2 的值。
  • 赋值运算符【12】:赋值运算符的作用就是将常量、变量或表达式的值赋给某一个变量,,赋值符号 " = " 可以和算术运算符结合成复合赋值运算符,例如=  +=  -=  *=  /=  %=  &=  |=  ^=  ~=  <<=  >>=  >>>=
  • 字符串连接运算符【1】:主要用来将和字符串连接的内容转为字符串**(+)**

以上这些运算符的优先级排序如下:
在这里插入图片描述

括号级别最高,逗号级别最低,单目 > 算术 > 位移 > 关系 > 逻辑 > 三目 > 赋值

语句

语句分为条件语句以及循环语句,接下来分别举例说明。

条件语句

条件语句有两种,if+else和switch:

public static void main(String[] args) {
		int i = 7;
		if (i < 20) {
			System.out.println("free");
		} else if (i < 40) {
			System.out.println("normal:100yuan");
		} else if (i < 60) {
			System.out.println("free");
		} else {
			System.out.println("ok,you are right");
		}
}

switch语句如下所示:

public class choose {
	public static void main(String[] args) {
		int i = 7;

		switch (i) {                       //java中的switch只能探测int型的数据
		case 3:
			System.out.println(33);
			break;                      //每个break必须要打,如果没有,就会发生case穿透问题,直接连同下一个case内容都打印出来
		case 4:
		case 7:
		case 12:                          //多个case可以合并到一起,是或的关系
			System.out.println(44);
			break;
		case 5:
			System.out.println(55);
			break;

		default:                              //default可以省略,但最好不要省略,破坏了程序的健壮性
			System.out.println("error");
			break;
		}
	}

循环语句

循环语句分为for循环语句、while语句以及do-while语句:

  • for循环语句,一般有固定的循环次数
    在这里插入图片描述
  • while和do-while循环语句,一般没有固定的执行次数,其中while先判断再执行,do-while则先执行再判断
    在这里插入图片描述
  • 循环终止语句break和continue: break表示跳出,continue表示终止本次循环
    在这里插入图片描述

以下为一个循环代码的示例:

	public static void main(String[] args) {
			int result = 0;
			for (int i = 1; i <= 99; i += 2) {
				result += i;
			}
			System.out.println(result);
	
			int x = 0;
			
			while (x < 10) {
				System.out.println(x);
				x++;
			}                     //while....是先判断条件然后执行语句
	
			x = 0;       
			do {                  //do...while是先执行一次再判断条件
				x++;
				System.out.println(x);
			} while (x < 10);     //注意后边的分号!!
			
			int stop=4;
			for(int i=1;i<=10;i++){
				if(i==stop) break;   //注意if语句后边不要加分号!!!!
				System.out.println("i="+i);    //终止整个语句块儿的循环,跳出循环语句
			}
			
			int skip=3;
			for(int i=1;i<=10;i++){
				if(i==skip) continue;    //终止本次值的循环,直接跳到下一次
				System.out.println("i="+i);
			}
			
			System.out.println(fabonacciloop(-3));        //用循环的方式解决斐波那契数列问题
		}
		

分支+循环解决斐波那契数列问题:

public static long fabonacciloop(int index) {
		if (index<1) {
			System.out.println("erro");
				return -1;
		}
		if (index == 1 || index == 2) {
			   return 1;
		} else {
				long f1 = 1L;
				long f2 = 1L;
				long f = 0L;
				for (int i = 3; i <= index; i++) {
					f = f1 + f2;
					f1 = f2;
					f2 = f;                        //循环,变量互换赋值
		
				}
					return f;
			}
		
		}

更多的测试代码如下:

	public static void main(String[] args) { //每隔5个为一行打印出100内能被3整除的数
			int num = 0;
			for (int i = 0; i < 100; i++) {     //0~100之内能被3整除的数
				if (i % 3 == 0) {
					System.out.println(i);
					num++;
				}
				if(num==5){
					break;                    //如果计数达到5个可以被3整除,则终止计数
				}
			}
public class testloop {     //打印出100--200之间所有的质数
			for (int i = 101; i < 200; i+=2) {
				boolean f=true;
				for (int j = 2; j < i; j++) {
					if (i%j==0) {
						f=false;           //如果不是质数,设f为false,然后终止本次循环
						break;              //注意,这里只是把内层循环终止了
					}
				}
				if(!f){                    //如果不是质数,执行跳过,没跳过的都是质数,打印出来
					continue;
				}
				System.out.println(i);
			}
		}

方法

方法表示一段特定功能的代码,包含:形参、实参、返回值、返回值类型、方法名

public class testmethod {
	public static void main(String[] args) {    //主车间,进行组装的地方
		m();
		m2(2);                                //这里传入的4, 相当于实参,实际传入的参数
		m3('3', 4);
		m4(4, 6);                                //有返回值,但是并没有被打印出来
		/*int i = m4(4, 6);
		System.out.println(i);*/                 //把该返回值传给i,然后打印出该返回值
		}
	
	public static void m() {                //该分车间不返回任何值,只是顺序执行
		//return;                           //直接return会报错,因为没有任何语句得到执行
		System.out.println("ok");
		System.out.println("hello");
	}
	
	public static void m2(int i) {             //形式参数i,必须传入一个值且必须为int类型的
		if(i > 3) 
			return;
		System.out.println(i);
	}
	
	public static void m3(int i, int j) {     //该分车间可以有两个
		System.out.println(i + j);
	}
	
	public static int m4(int i, int j) {      //该分车间具有返回值
		return i > j ? i : j;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

存在morning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值