Java基础语法

我们为什么需要Java语法?

  程序语言,就是一种用来与机器交流的语言,和中文、英语、日语一样,每种程序语言都有着自己的语法,掌握了这些基础语法,就能与机器进行正常的沟通交流。而进行写英语作文一样写出更复杂的代码,也是都基于基础语法的。Java基础语法,就是Java体系万丈高楼的基石,基石不牢,万丈高楼亦可平。基础语法虽不难但也得认真对待,于细微之处见真章。好在高级程序语言的基础语法基本类似,真正理解了其中一种语言的基础语法,其他语言便可以很快上手。

标识符

Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

关于 Java 标识符,有以下几点需要注意:

  • 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始
  • 首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
  • 关键字不能用作标识符
  • Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
  • 合法标识符举例:age、$salary、_value、__1_value
  • 非法标识符举例:123abc、-salary

基本命名规则

起名字,确实是一个很让人头痛的问题。命名时,我们除了需要做到见词知意外,还需要遵守以下几个基本规则:

  • 类名:类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
  • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写,如eatFood()。
  • 源文件名:源文件名必须和被public修饰的类名相同。(如果不相同则会导致编译错误)。
  • 主方法入口:主程序入口写法为固定的: public static void main(String []args) ,Java程序从该方法开始执行。

关键字

  关键字,也被叫为保留字。(此处又想吐槽IT业内对同一个东西有多个名词称呼的问题)就是这些名字,已经被系统设计时就占用了,我们再取名时,就不能和关键字重名。
Java关键字如下表:

类别关键字说明
访问控制private私有的
protected受保护的
public公共的
default默认
类、方法和变量修饰符abstract声明抽象
class
extends扩充,继承
final最终值,不可改变的
implements实现(接口)
interface接口
native本地,原生方法(非 Java 实现)
new新,创建
static静态
strictfp严格,精准
synchronized线程,同步
transient短暂
volatile易失
程序控制语句break跳出循环
case定义一个值以供 switch 选择
continue继续
default默认
do运行
else否则
for循环
if如果
instanceof实例
return返回
switch根据值选择执行
while循环
错误处理assert断言表达式是否为真
catch捕捉异常
finally有没有异常都执行
throw抛出一个异常对象
throws声明一个异常可能被抛出
try捕获异常
包相关import引入
package
基本类型boolean布尔型
byte字节型
char字符型
double双精度浮点
float单精度浮点
int整型
long长整型
short短整型
变量引用super父类,超类
this本类
void无返回值
保留关键字goto是关键字,但不能使用
const是关键字,但不能使用
null 空

基本数据类型

  Java中数据类型的分为基本数据类型与引用数据类型。其中引用数据类型属于面向对象范围,将在面向对象篇章中整理。基本数据类型,一共有八个。数据类型图示如下:

数据类型
基本数据类型
引用数据类型
数值型
字符型char
布尔型boolean
整数类型:byte\short\int\long
浮点类型:float\double
类class
接口interface
数组

基本数据类型的

数据类型占用空间最小值最大值默认值
byte8位,1字节-128(-2^7)127(2^7-1)0
short16位,2字节-32768(-2^15)32767(2^15 - 1)0
int32位,4字节-2^312^31 - 10
long64位,8字节-2^632^63 - 10L
float32位,4字节-2^1282^1280.0f
double64位,8字节-2^10242^10240.0d
char16位,2字节\u0000(即为0)\uffff(即为65,535)‘u0000’
boolean4字节,布尔数组1字节,取决于JVMfalse

转义字符

Java语言支持一些特殊的转义字符序列。

符号含义
\n换行 (0x0a)
\r回车 (0x0d)
\f换页符(0x0c)
\b退格 (0x08)
\0空字符 (0x20)
\s字符串
\t制表符
"双引号
单引号
\反斜杠
\ddd八进制字符 (ddd)
\uxxxx16进制Unicode字符 (xxxx)

运算符

算术运算符

  算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符,表中我们设整数变量A的值为10,变量B的值为20。

运算符描述示例
+加法 - 相加运算符两侧的值A + B 等于 30
-减法 - 左操作数减去右操作数A – B 等于 -10
*乘法 - 相乘操作符两侧的值A * B等于200
/除法 - 左操作数除以右操作数B / A等于2
取余 - 左操作数除以右操作数的余数B%A等于0
++自增: 操作数的值增加1B++ 或 ++B 等于 21
自减: 操作数的值减少1B-- 或 --B 等于 19

自增自减

  自增(++)自减(–)是种特殊的算术运算符。在运算结果不继续参与其他运算时,运算符++/–放在前面或后面效果一样,都是等效于自身+1或-1。

我们设:a = 10; b = 20;
a++ 与 ++a 都等效于 a = a + 1;计算完成后,a的值为11。
a-- 与 --a 都等效于 a = a - 1;计算完成后,a的值为9。

如果自增自减后,还要参与运算,则运算符放在前与放在后是不一样的。

前缀自增自减法(++a,–a)时: 先进行自增或者自减运算,再进行表达式运算。

后缀自增自减法(a++,a–)时: 先进行表达式运算,再进行自增或者自减运算。

int a = 10;
int b = 20;
int x = 2*++a;
int y = 2*b++;
System.out.println("自增运算符前缀运算后a="+a+",x="+x);
System.out.println("自增运算符后缀运算后b="+b+",y="+y);
---------------------------------------------------------
输出结果:
自增运算符前缀运算后a=6,x=12
自增运算符后缀运算后b=6,y=10

关系运算符

  我们设整数变量A的值为10,变量B的值为20。

运算符描述示例
==检查如果两个操作数的值是否相等,如果相等则条件为真。( A == B )为false
!=检查如果两个操作数的值是否相等,如果值不相等则条件为真。( A != B )为true
>检查左操作数的值是否大于右操作数的值,如果是那么条件为真。( A> B )为false
<检查左操作数的值是否小于右操作数的值,如果是那么条件为真。( A <B )为true
>=检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。( A> = B )为false
<=检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。( A <= B )为true

位运算符

  Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
  我们设整数变量A的值为60,变量B的值为13。

运算符描述示例
如果相对应位都是1,则结果为1,否则为0(A&B),得到12,即0000 1100
|如果相对应位都是 0,则结果为 0,否则为 1(A | B)得到61,即 0011 1101
^如果相对应位值相同,则结果为0,否则为1(A ^ B)得到49,即 0011 0001
按位取反运算符翻转操作数的每一位,即0变成1,1变成0。(〜A)得到-61,即1100 0011
<<按位左移运算符。左操作数按位左移右操作数指定的位数。A << 2得到240,即 1111 0000
>>按位右移运算符。左操作数按位右移右操作数指定的位数。A >> 2得到15即 1111
>>>按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。A>>>2得到15即0000 1111
A = 0011 1100
B = 0000 1101
-----------------
则:
A&B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011

逻辑运算符

  我们设变量A为true,变量B为false。

运算符描述示例
&与- 当且仅当两个操作数都为true,结果才为true,否则为false。( A & B )为false
|或 - 当两个操作数中有一个为true,结果就为true。( A | B )为true
&&短路与 - 只要有一个操作数为false,直接返回结果为false。( A && B )为false
| |短路或 - 只要有一个操作数为true,直接返回结果为true。( A | | B )为true
!非 - 用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符的结果为false。! B 为true
^异或 - 两个操作符相同为false,不同为true。( A ^ B )为false

短路与、短路或

  在Java中,需要注意“短路与、短路或”虽然最终结果和“与、或”相同,但是计算过程是有差异的。短路的含义,就是当从判断第一个操作符就可以知道结果时,就不会再执行第二个操作符的语句。而使用与、或的情况下,是会执行的。举一个例子对比一下:

//短路与
int a = 5;
boolean b = (a<4) && (a++<10);
System.out.println("使用短路逻辑运算符的结果为:"+b);
System.out.println("a的结果为:"+a);
--------------
输出结果为:
使用短路逻辑运算符的结果为:false
a的结果为:5
//与
int a = 5;
boolean b = (a<4) & (a++<10);
System.out.println("使用短路逻辑运算符的结果为:"+b);
System.out.println("a的结果为:"+a);
--------------
输出结果为:
使用短路逻辑运算符的结果为:false
a的结果为:6

赋值运算符

  下面是Java语言支持的赋值运算符:

运算符描述示例
=简单的赋值运算符,将右操作数的值赋给左侧操作数C = A + B将把A + B得到的值赋给C
+ =加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数C + = A等价于C = C + A
- =减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数C - = A等价于C = C - A
* =乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数C * = A等价于C = C * A
/ =除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数C / = A,C 与 A 同类型时等价于 C = C / A
(%)=取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数C%= A等价于C = C%A
<< =左移位赋值运算符C << = 2等价于C = C << 2
>> =右移位赋值运算符C >> = 2等价于C = C >> 2
&=按位与赋值运算符C&= 2等价于C = C&2
^ =按位异或赋值操作符C ^ = 2等价于C = C ^ 2
| =按位或赋值操作符C | = 2等价于C = C | 2

字符串连接符

  Java中有一个非常快捷的将两个字符串连接起来的运算符,就是:+ ,参与 + 运算的变量中有一个为字符串,那么+就不再代表相加的意思, 而是表示字符串连接,就算参与运算的另一个变量不是变量而是数值型,连接结果依旧会为字符串类型。

运算符描述示例
+字符串连接符,相加结果为字符串类型“2” + 2 = “22”

  多个+运算时,从左往右进行计算,如果同时有字符串和数值型进行计算时,要注意上什么时候计算结果变为了字符串类型。举一个例子,方便理解:

System.out.println(1+2+3);
System.out.println("1"+2+3);
System.out.println(1+"2"+3);
System.out.println(1+2+"3");
----------------------------------
输出结果为:
6		//数值类型
123		//字符串类型
123		//字符串类型
33		//字符串类型

条件运算符(?:)

  条件运算符也被称为三元运算符,该运算符比较特殊,是Java中唯一的三元运算符,其他运算符都是二元,条件运算符的运算规则如下:

运算符描述示例
? :?前的操作数为true时,则返回:前的操作数,否则返回:后的操作数( 1 == 1 ) ?2:3,返回值为2

操作数可以是一个数值,也可以是表达式。需要注意的是,条件运算符判断第一个操作数后,根据判断结果去选择执行:前、后的操作数,不会都执行。举例:

int a = 10;
int b = ( a == 11 ) ? ( ++a ) : ( --a ) ;
System.out.println("运行后a的值为:"+a);
System.out.println("运行后b的值为:"+b);
----------------------------------
输出结果:
运行后a的值为:9  //如果++a也运行了,a的值应该会为10。证明不会运行。
运行后a的值为:9

instanceof 运算符

  该操作符用于判断操作对象是否是某一个特定的类型(类类型或接口类型)。

运算符描述
instanceof判断操作对象是否是某一个特定的类型

示例:

String name = "HHM";
boolean result = name instanceof String; 
System.out.println("result:"+result );
----------------------------------
输出结果:
result:true		// 由于 name 是 String 类型,所以返回真
class Animal {}
 
public class Cat extends Animal {
   public static void main(String[] args){
      Animal a = new Cat();
      boolean result =  a instanceof Cat;
	  System.out.println("result:"+result );
   }
}
输出结果:
result:true

运算符优先级

  当写比较复杂的判断条件等情况的时候,一长串的运算符执行顺序是怎么样的呢?这就涉及到运算符的优先级别的问题。在一个多运算符的表达式中,运算符优先级不同会导致最后得出的结果差别甚大。下表列出了运算符的优先级,数字小的,优先级高,先执行。

优先级运算符结合性
1() [] . (点操作符)左到右
2+ + - !〜从右到左
3* /%左到右
4+ -左到右
5>> >>> <<左到右
6>> = << =左到右
7== !=左到右
8左到右
9^左到右
10|左到右
11&&左到右
12| |左到右
13?:从右到左
14= + = - = * = / =%= >> = << =&= ^ = |=从右到左

  但建议在写复杂的运算逻辑时,多用 ( ) ,将想要先进行运算的表达式括起来先执行,这样不仅可以不用为优先级排序而头痛,还可以增强可读性。

类型转换

  在日常开发过程中,常有需要将一些数据类型相互转换,然后再进行计算的问题。这时就需要涉及类型转换的问题。类型转换大致分为两类:自动类型转换 与 强制类型转换。
  数据类型转换时有如下规则:

  1. 不能对boolean类型进行类型转换。
  2. 不能把对象类型转换成不相关类的对象。
  3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
  4. 转换过程中可能导致溢出或损失精度。

自动类型转换

  进行自动类型转换,需满足转换前的数据类型的容量(取值范围)要低于转换后的数据类型,如long型就可以自动转换为float型。

	   float a = 11223344L;   // √ , 11223344L 为long类型,可以转换
	   long b = 11.22f;		  // × , 11.22f 为float类型,不可以转为long类型

  特例:我们输入的整数,实际就是int类型,可以直接赋值给byte类型,但不能超过byte的容量范围。这里其实也进行了数据类型的转换,可以看作是进行了自动类型转换,也可以看作进行了隐式的强制类型转换。Java这种设计并不是莫名其妙想搞特例,而是为了方便日常编程。

	   byte c = 127;		  // √ , 127 为 int类型,但可以赋值给byte
	   byte d = 128;	      // × , 128 为 int类型,但超出了byte范围

强制类型转换

  当我们需要把容量大的数据类型转换为容量小的数据类型时,就需要使用强制类型转换。转换实现如下:

	   int a = 123;
       byte b = (byte)a;//强制类型转换为byte
       System.out.println("int强制类型转换为byte后的值等于="+b);
--------------------------------------------
输出结果为:
int强制类型转换为byte后的值等于=123

精度丢失问题

  在浮点数到整数的强制转换过程中,是通过舍弃小数得到,而不是四舍五入,举例:

double a = 3.14f;
int b = (int)a;
System.out.println("b = " + b);
--------------------------------------------
输出结果为:
b = 3  		// 精度损失,舍弃小数,而不是四舍五入

溢出问题

  进行强制类型转换时,我们需要格外注意一些溢出问题:
  1.超出容量范围造成溢出。这种需要避免,不能进行这样的类型转换。

int a = 128;
byte b = (byte)a;
System.out.println("b = " + b);
--------------------------------------------
输出结果为:
b = -128  		// 因为128超出了byte范围,造成溢出

  2.计算过程中造成溢出,需要在计算前进行数据类型转换。

	   int a = 100000000;
	   int b = a*20;		// 范围内,未溢出情况
	   int c = a*30;		// 超出范围,溢出
	   long d = a*30;		// 计算时已超出范围,再赋值给容量大的类型也为时已晚
	   long e = (long)a*30;	// 先进行强制数据类型转换,保证计算结果为容量更大的类型
	   long f = a*30L;		// 先声明其中一个参与计算的数字为容量更大的类型
	   System.out.println("b = " + b);
	   System.out.println("c = " + c);
	   System.out.println("d = " + d);
	   System.out.println("e = " + e);
	   System.out.println("f = " + f);
--------------------------------------------
输出结果为:
b = 2000000000
c = -1294967296
d = -1294967296
e = 3000000000
f = 3000000000

流程控制语句

  流程控制语句是用来控制程序中各语句执行顺序的语句, 可以把语句组合成能完成一定
功能的小逻辑模块。
  其流程控制方式采用结构化程序设计中规定的三种基本流程结构, 即: 顺序结构、 选择
结构和循环结构, 如下图所示:
在这里插入图片描述

顺序结构

  Java代码,都是从上至下,一行一行按顺序运行的,这就时顺序结构。

选择结构

  有些时候,我们需要有选择地执行或不执行某些特定的语句,这时候我们就需要选择结构。

if else 语句

  最基本的 if 语句包含一个布尔表达式和一条或多条语句。如果布尔表达式为true则紧跟的语句将被执行,否则跳过。在此基础上可以使用else,else后紧跟的语句将在布尔表达式为false时执行,否则跳过。并且可以使用else if,在第一个布尔表达式为false时,进一步进行另一个布尔表达式的判断。当然,if else后面紧跟的语句可以为任何语句,包括if else语句。
  if语句语法格式如下:

if(布尔表达式)
{
   //如果布尔表达式为true将执行的语句,否则将跳过
}

  if else语句语法格式如下:

if(布尔表达式){
   //如果布尔表达式的值为true将执行的语句,否则将跳过
}else{
   //如果布尔表达式的值为false将执行的语句,否则将跳过
}

  if else if else语句语法格式如下:( 需要注意Java中else if中间是有空格的,有些编程语言里是连着的:elseif )

if(布尔表达式 1){
   //如果布尔表达式 1的值为true执行代码,否则将跳过
}else if(布尔表达式 2){
   //如果布尔表达式 2的值为true执行代码,否则将跳过
}else if(布尔表达式 3){
   //如果布尔表达式 3的值为true执行代码,否则将跳过
}else {
   //如果以上布尔表达式都不为true执行代码,否则将跳过
}

  嵌套的 if…else 语句语法格式如下:

if(布尔表达式 1){
   如果布尔表达式 1的值为true执行代码
   if(布尔表达式 2){
      如果布尔表达式 2的值为true执行代码
   }
}

switch case 语句

  使用if else if else语句,特别时当选择条件过多时,会显得代码十分复杂且累赘。这时我们可以使用Java提供的另一种选择语句来达成相同的目的:switch case语句。
  switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。switch case 语法格式如下:

switch(expression){
    case value :
       //语句
       break; //可选
    case value :
       //语句
       break; //可选
    //你可以有任意数量的case语句
    default : //可选
       //语句
}

switch case 语句有如下规则:

  • switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。

  • switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。

  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。

  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。

  • 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。

  • switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

循环结构

  顺序结构的程序语句只能被执行一次。如果想要同样的操作执行多次,,就需要使用循环结构。

while 循环语句

  while是最基本的循环,它的语法格式为:

while( 布尔表达式 ) {
  //循环中被执行的语句  只要布尔表达式为 true,循环就会一直执行下去。
}

do…while 循环语句

  do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次,在第一次循环完成后再判断尔表达式是否为true,以决定是否进入下一次循环。do…while 的语法格式如下:

do {
  //循环中被执行的语句  如果布尔表达式为 true,循环就会一直执行下去。
}while(布尔表达式);

for 循环语句

  虽然所有循环结构都可以用 while 或者 do…while表示,但 Java 提供了另一种语句 —— for 循环,使一些循环结构变得更加简单。

  for循环执行的次数是在执行前就确定的。语法格式如下:

for(初始化; 布尔表达式; 更新) {
  //循环中被执行的语句  如果布尔表达式为 true,循环就会一直执行下去。
}

实例:

      for(int x = 1; x < 10; x++) {
         System.out.print( x );
         System.out.print( "," );
      }
-------------------------------------------
输出结果为:
1,2,3,4,5,6,7,8,9,

关于 for 循环有以下几点说明:

  • 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
  • 然后,检测布尔表达式的值。如果为 true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
  • 执行一次循环后,更新循环控制变量。
  • 再次检测布尔表达式。循环执行上面的过程。

Java 增强 for 循环,foreach

  Java5 引入了一种主要用于数组的增强型 for 循环。Java 增强 for 循环语法格式如下:

for(type element: array)
{
   //代码句子
}

  在声明语句中,声明的变量是来循环取用数组中的元素,声明的变量并不是数组元素本身,所有对声明的变量的修改等操作,并不会影响数组本身。实例:

public class Test {
	public static void main(String[] args){
		  int [] numbers = {10, 20, 30, 40, 50};
		  //尝试修改
		  System.out.print("尝试修改:");
		  for(int x : numbers ){
		         x = x*10;
		         System.out.print(x);    //只是修改了该代码块中的x,数组实际未改变
		         System.out.print(",");
		      }
		  System.out.print("\n");
		  //数组实际
		  System.out.print("数组实际的值:");
	      for(int x : numbers ){
	         System.out.print( x );
	         System.out.print(",");
	      }
    }
}
-------------------------------------------
输出结果为:
尝试修改:100,200,300,400,500,
数组实际的值:10,20,30,40,50,

break与continue

  break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块,并且继续执行该循环下面的语句。

  continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。在 for 循环中,continue 语句使程序立即跳转到更新语句。在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

枚举

  Java 5.0引入了枚举,枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的 bug。

  例如,我们为果汁店设计一个程序,它将限制果汁为小杯、中杯、大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。实例:

class FreshJuice {
   enum FreshJuiceSize{ SMALL, MEDIUM , LARGE }
   FreshJuiceSize size;
}
 
public class FreshJuiceTest {
   public static void main(String []args){
      FreshJuice juice = new FreshJuice();
      juice.size = FreshJuice.FreshJuiceSize.MEDIUM; //只能为enum中设定的SMALL, MEDIUM , LARGE
   }
}

注释

  类似于 C/C++,Java 也支持单行以及多行注释。注释中的字符将被 Java 编译器忽略,不会编译为字节码。单行注释使用 // ,多行使用 /* /。除此之外,还有文档注释,以 /* 开始,以 */结束,主要用于对编写的类、变量和方法进行说明,再使用这些类、变量和方法时,就可以看见这些注释。示例:


//  System.out.println("Hello World");  单行注释,被注释的代码不会编译,也不会执行

/*  多
* 	行
*   注
*   释
*/

/**  文档注释
*  @author  HHM
*  @version 1.0
*/

  写代码一定多写一点注释,用文字描述一下程序设计的关键点等,方便自己及他人阅读。

  在结尾,欢快一点,我正好想起了一个程序员点菜段子,点了鱼香肉丝但不想要了。
  程序员://鱼香肉丝
  正常人:鱼香肉丝

  我自知我文章写的不行,但如果这个有被这个段子笑到,给我点个赞吧,哈哈~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值