03Java基础语法
关键字、标识符、注释、常量
关键字
1. 被Java语言赋予特定含义的单词
2. 特点:组成关键字单词的字母全部小写。
3. 注意:
A. goto和const是保留字
B. 类似于 Notepad++、EditPlus 这样的高级文本编辑器,针对关键字都有特殊的颜色标记。
标识符
1. 给类,接口,方法,变量等起名字的字符序列
2. 组成规则:
A. 英文大小写字母
B. 数字
C. $和_
3. 注意事项:
A. 不能以数字开头
B. 不能是java中的关键字
C. 区分大小写
4. 常见的命名规则(见名知意)
A. 包 全部小写
单级包:小写
举例:liuyi、com
多级包:小写,并用 ‘.’ 隔开
举例:cn.itcast、com.baidu
B. 类或者接口
一个单词:首字母大写
举例:Student,Demo
多个单词:每个单词首字母大写
举例:HelloWorld,StudentName
C. 方法或者变量
一个单词:首字母小写
举例:name,main
多个单词:从第二个单词开始,每个单词首字母大写
举例:studentAge,showAllNames()
D. 常量 全部大写
一个单词:大写
举例:PI
多个单词:大写,并用 ‘_’ 隔开
举例:STUDENT_MAX_AGE
注释
1. 单行注释 //
2. 多行注释 /**/
3. 文档注释 /** */
常量
1. 在程序执行的过程中,其值不发生改变的量
2. 分类:
A. 字面值常量
B. 自定义常量(后面讲)
3. 字面值常量
A. 字符串常量 “hello”
B. 整数常量 12、23
C. 小数常量 12.345
D. 字符常量 ‘a’、’A’、’0’
E. 布尔常量 true,false
F. 空常量 null
4. 在Java中针对整数常量提供了四种表现形式
A. 二进制 由0,1组成。以0b开头。
B. 八进制 由0,1,…7组成。以0开头。
C. 十进制 由0,1,…9组成。整数默认是十进制。
D. 十六进制 由0,1,…9,a,b,c,d,e,f(大小写均可)组成。以0x开头。
System.out.println(100); //十进制
System.out.println(0b100); //二进制
System.out.println(0100); //八进制
System.out.println(0x100); //十六进制
数据类型
Java是一种强类型语言,针对每种数据都提供了对应的数据类型。
JAVA只有两种数据类型:基本数据类型,引用数据类型
基本数据类型:8种
注意:Java基本类型长度固定,和系统位宽无关
整数
JAVA中没有无符号的整数。JAVA中整数可以表示十进制,二进制(以0b开头),八进制(以0开头),十六进制(以0X或0x开头)。
byte
1个字节,-27—27-1
8位带符号数
1 | byte b1 = 127; |
short
2个字节,-215—215-1
16位带符号数
int
4个字节,-231—231-1,JAVA中的整数默认为int类型。
32位带符号数
long
8个字节,-263—263-1,在整数的后面加L或l表示long类型的整数。
64位带符号数
浮点数
浮点数的运算会产生误差。
float
4个字节,在浮点数后面加F或f.
32位,标准IEEE 754
double
8个字节,JAVA中浮点数默认为double类型。
64位,标准IEEE 754
字符类型
char
2个字节,值必须放在一对单引号中,并且单引号中只能有一个字符。
值必须放在一对单引号中,并且单引号中只能有一个字符。
JAVA使用Unicode编码集,所有的字符均为2个字节,所以 Java 语言中的字符 char 可以存储一个中文汉字。
ASCII码
‘a’ 97
‘A’ 65
‘0’ 48
布尔类型
boolean
1个字节,只有两个值:true、false。JAVA中boolean类型不能转换为其它类型。占用1个字节。
Demo
1 | class DataTypeDemo { |
引用数据类型
类
接口
数组
枚举
注解
字符串
字符串转义陷阱
1 | System.out.println("\045678"); // 输出 %678 |
声明
变量
a) 格式:数据类型 变量名[=值];
b) JAVA是强类型的语言。
c) 当变量没有赋值时不能使用,否则编译失败。
d) 在同一个范围内不能出现同名的变量。
e) 标识符(类名,变量名,方法名,包名等)的命名规则:
i. 标识符由字母,数字,下划线,美元符组成。
ii. 不能使用数字开头。
iii. 不能使用关键字(JAVA中关键字均为小写)。
f) Java命名规范:变量名均为小写。如果变量名由多个单词组成,从第二个单词开始,每个单词首字母大小,其它均为小写(如:userName,userAge,password)
常量(最终变量)
a) 使用final关键字。
final datatype CONSTANTNAME = VALUE;
final double PI = 3.14159;
b) 从不改变的永久数据(即常量只能赋值一次)
类型转换
基本数据类型的类型转换
基本类型比较大小
先比较精度,精度大的类型大。如果精度相同,比较字节数,字节数大的类型大。
自动转换
JVM会自动将小类型转换为大的类型。
1 | byte b1 = 127; |
从小到大:byte,short,char—int—long—float—double
float 比 long类型大?
long:8个字节 -263 ~ 263-1
float:4个字节 -3.4028235E+38~3.4028235E+38
3.4*1038 > 2*1038 > 2*838 = 2*(23)38 = 2*2114 > 263-1
它们的底层存储结构不同,float表示的数据范围比long的范围要大。
手动转换(强制转换)
使用:将大类型转换为小类型。精度损失问题
格式:目标数据类型 变量名 = (目标数据类型) (被转换的数据);
注意: boolean类型不能转换为其他的数据类型
默认转换(从小到大的转换)
A:byte,short,char—int—long—float—double
B:byte,short,char相互之间不转换,他们参与运算首先转换为int类型。
Demo
1 | // 定义一个byte类型,一个int类型,做加法 |
思考题
一:哪句是编译失败的呢?为什么呢?
byte b1=3,b2=4,b;
b=b1+b2; //有问题的,是类型提升。先将b1和b2转换为int型后参与运算。
b=3+4; //只要整形直接量是在目标变量允许的范围内,那么将整形直接量赋给short型或byte型变量时,就不需要显示的类型转换。
二:分析
1 | byte a = 130; // 有问题,因为byte的范围是:-128到127。 |
三:找问题
1 | double d = 12.345; |
四:下面两个定义有没有区别?
1 | float f1 = (float) 12.345; // f1其实是通过一个double类型转换过来的。 |
字符型与数值型的转换
char型 转 数值型
char型数据可以转换成任意一种数值类型
char型数据转换成数值型,字符的统一码就被转换成某个特定的数值。
1 | int i = (int)'A';; |
数值型 转 char型
整数转换成char类型,只用到该数据的低十六位,其余部分都被忽略。例如:
1 | char ch = (char)0XAB0041; |
浮点型转换成char型,首先将浮点值转换成int型,然后将int型转换为char型。
1 | char ch = (char)65.25; |
提示
转换结果适用于目标变量,就可以使用隐士转换方式;否则,必须使用显示转换方式:
1 | byte b = 'a'; // 隐士转换 |
因为统一码 \uFFF4 不适用于一个字节范围内,下面的转换就是不正确的:
1 | byte b = '\uFFF4'; |
为了强制赋值,就必须使用显示转换方式:
1 | byte b = (byte) '\uFFF4'; |
总结
所有数值运算符都可以用在char型操作数上。
如果另一个操作数是一个数字或字符,那么char型操作数就会被自动转换成一个数字。
如果另一个操作数是一个字符串,字符就会与该字符串相连。
字符参与运算
是查找ASCII里面的值
‘a’ 97
‘A’ 65
‘0’ 48
System.out.println(‘a’);
System.out.println(‘a’ + 1);
字符串参与运算
这里其实是字符串的连接
System.out.println(“hello”+’a’+1); // helloa1;字符串数据和其他数据做+,结果是字符串类型。这里的+不是加法运算,而是字符串连接符。
System.out.println(‘a’+1+”hello”); //结果为:98hello ‘a’是字符不是字符串
System.out.println(“5+5=”+5+5); //5+5=55
System.out.println(5+5+”=5+5”); //10=5+5
运算符
显示当前时间
a). 调用System.currentTimeMillis()方法获取存放在变量totalMilliseconds中从1970年1月1日午夜到现在的毫秒数(例如:1203183086328毫秒)。
b). 通过将总毫秒数totalMilliseconds除以1000得到总秒数totalSeconds(例如:1203183086328毫秒/1000 = 1203183086秒)。
c). 通过totalSeconds%60得到当前的秒数(例如:1203183086秒%60 = 26,这个值就是当前秒数)。
d). 通过将totalSeconds除以60得到总的分钟数totalMinutes(例如:1203183086秒/60 = 20053051分钟)。
e). 通过totalMinutes%60得到当前分钟数(例如:20053051分钟%60 = 31,这个值就是当前分钟数)。
f). 通过将总分钟数totalMinutes除以60获得总的小时数totalHours(例如:20053051分钟/60 = 334217小时)。
g). 通过totalHours%24得到当前的小时数(例如:334217小时%24 = 17,该值就是当前小时数)。
算术运算符
+,-,*,/,%,++,–
a). +的用法
1:加法
2:正号
3:字符串连接符
System.out.println(“hello”+’a’+1); helloa1
System.out.println(‘a’+1+”hello”); 98hello
b). /和%的区别
数据做除法操作的时候,/取得是商,%取得是余数
1 | int x = 3, y = 4; |
c). 算术运算结果的类型
1. 当参与运算的元素类型相同时,结果的类型一定与运算元素的类型一致。
2. 当参与运算的元素类型不同时,结果的类型一定与运算中类型大的元素类型一致。
1 | short s = 1; //值在类型的取值范围内时,JVM会自动将值转换为需要的类型 |
d). ++ 和 –
++/–可以出现在变量的前面/后面。无论出现在前面/后面,代码执行后变量一定加1/减1
++/–出现在前面:先参与计算,再取值。
++/–出现在后面:先取值,再参与计算。
int y = (x++)+(++x)+(x*10); //4+6+60
1 | //交换两个变量的值(不通过第三个变量实现) |
比较运算符
>,>=,<,<=,==,!=
a). 比较运算的结果一定为boolean类型。
b). JAVA中不是所有的类型都可以使用比较运算符进行比较。如:boolean与其它类型。基本数据类型不能与引用数据类型进行比较。
逻辑运算符
&,|,!,&&,||,^
a). 逻辑与(&),逻辑或(|)
b). 短路与
&&,当第一个表达式为false时,不执行第二个表达式,直接返回false
c). 短路或
||,当第一个表达式为true时,不执行第二个表达式,直接返回true
d). 逻辑非
!,取反
e). 异或^
相同则false,不同则true。
扩展运算符
+=,-=,*=,/=,%=,扩展运算符会自动转换结果的类型
1 | short s = 1; |
位运算符
&,|,^,~,<<,>>,>>>
a). 与、或、异或、取反
注意:
要做位运算,首先要把数据转换为二进制。
1 | // &,|,^,~ |
一个数据针对另一个数据位异或两次,该数不变
1 | int a = 10; |
b). 左移、右移、无符号右移
左移(<<) 左边最高位丢弃,右边补齐0
右移(>>) 右边数值位丢弃,最高位是0,左边补齐0;最高为是1,左边补齐1
无符号右移(>>>) 右边数值位丢弃,无论最高位是0还是1,左边补齐0
思考题
一:请用最有效率的方式计算出2乘以8的结果
2<<3
1 | // <<,把<<左边的数据乘以2的移动次幂 |
二:请实现两个变量的交换
int a = 10;
int b = 20;
方式1:采用第三方变量
1 | int c = a; |
方式2:用位异或运算符(面试用)
1 | // 左边a,b,a |
方式3:用变量相加的做法
1 | a = a + b; //a=30 |
方式4:一句话搞定
1 | b = (a+b) - (a=b); //b=30-20=10,a=20 |
三元运算符(三目运算符)
x ? y : z ;x是一个boolean类型。当x为true时,返回y的值。当x为false时,返回z的值。
int z = ((x = y)? x : y); // 报错,这是赋值符号。
获取三个整数中的最大值
int a = 10,b = 30,c = 20;
int max2 = (a > b)?((a > c)? a: c):((b > c)? b: c);
int max2 = a > b?a > c? a: c:b > c? b: c; // 这种做法不推荐。
int i,j,k; i=j=k=1; // 该语句正确
键盘录入
1 | import java.util.Scanner; |
格式化输出
a) System.out.print(): //打印不换行。必须有参数。
b) System.out.println(): //将光标移到下一行(打印换行)。可以没有参数。
c) System.out.printf(“%f”,a); //格式化输出
1 | // 定义一些变量,用来格式化输出。 |
流程控制
顺序结构
从上往下,依次执行
选择结构
按照不同的选择,执行不同的代码
if 语句
格式(三种)
1 | if(布尔表达式){ |
注意事项
1) if语句中条件的结果必须为boolean类型。
2) 一个if语句中可以有0个或1个else语句。
3) else语句必须出现在if语句的最后。
4) 一个if语句中可以有0个或多个else if语句。
5) 当匹配到一个分支后,不再匹配其它的分支。
6) if的大括号可以省略,如果省略if的作用范围只有一行JAVA代码。
三元运算符和if语句第二种格式的关系
所有的三元运算符能够实现的,if语句的第二种格式都能实现。反之不成立,如果if语句第二种格式控制的语句体是输出语句,就不可以。因为三元运算符是一个运算符,必须要有一个结果返回,不能是一个输出语句。
switch 语句
格式:
1 | switch(switch表达式){ |
注意事项
1) switch语句中的表达式只能为byte,short,int,char。从JDK1.5开始可以使用枚举类型。从JDK1.7开始可以使用String。
2) case后面的值不能重复。
3) case后面只能为常量或字面值。
4) case后面可以为算术表达式。
5) 当匹配到一个分支后,switch会从此分支开始自顶向下执行所有的分支,直到switch的结束或遇到第一个break为止。
6) default可以出现在switch语句中的任意位置。
7) 无论default出现在哪,switch都会先匹配所有的case分支。如果没有匹配到任何case分支后,再执行default分支。
8) break可以省略,但是结果可能不是我们想要的。会出现一个现象:case穿透(如下示例)。建议不要省略
1 | switch (month) { |
9) default可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。
if 和 switch 的区别
if语句:
A:针对结果是boolean类型的判断
B:针对一个范围的判断
C:针对几个常量值的判断
switch语句:
针对几个常量值的判断
循环结构
做一些重复的代码
while循环
当不确定循环次数时,建议使用
格式:
1 | while(循环条件){ |
注意事项
1) 当循环条件返回true,执行循环。当循环条件返回false,结束循环。
2) 循环条件的结果必须为boolean类型。
3) while:先判断,再循环。
do..while循环
当不确定循环次数时,建议使用
格式:
1 | do { |
注意事项
1) 大括号不能省略。
2) do..while:先循环,再判断。至少会循环一次。
for循环
当确定循环次数时,建议使用
格式:
1 | for(初始操作;循环条件;每次迭代后的操作){ |
注意事项
1) for循环的三部分都可以省略。
2) Math.random():返回大于等于0.0,小于1.0的double类型的随机数。0.0—0.99999999999999999
3) for循环第一部分声明变量只能在for循环内使用。
4) for循环的第一部分可以同时声明多个类型相同的变量。
demo
一:求出1-100之间偶数和
1 | // 方式1 |
二:在控制台输出所有的”水仙花数”
水仙花数是指一个 n 位正整数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3+ 3^3 = 153)
这里以三位正整数为例:
1 | for (int x = 100; x < 1000; x++) { |
中断循环
1. break(中断):只能出现在switch语句与循环语句中。出现在循环语句中的作用:立即结束所在循环。
2. continue(继续):只能出现在循环语句。作用:立即结束本次循环,使所在循环直接进入下一次循环。
3. return(返回):用于结束方法的(作用不是结束循环),一旦遇到return,程序就不会在继续往后执行。
for 和 while 的区别
1. 使用上的区别
for语句的那个控制条件变量,在循环结束后不能在使用了。而while的可以继续使用。
2. 理解上的区别
for适合于一个范围的判断,while适合次数不明确的。
嵌套循环
1. 请输出一个4行5列的星星(*)图案
1 | /* |
2. 请输出下列的形状
1 | // * |
3. 在控制台输出九九乘法表
1 | // 1*1=1 |
数组
一组相同数据类型的集合。
JAVA中的数组都是引用数据类型。但数组中的元素可以为基本数据类型,也可以为引用数据类型。
一维数组
声明一维数组:数据类型[] 数组名/数据类型 数组名[];在栈中开辟一个空间,保存数据的名字(首地址)。在声明数组时不能指定数组的长度。
创建一维数组:在堆中开辟连续的空间。所以在创建数组时必须指定数组的长度。
1 | int[] array = { 10, 20, 30, 40 }; // 静态初始化,给出值,系统决定长度 |
注意事项
1. 使用下标访问数组中的元素,[]
2. 数组的下标从0开始,最大下标数组的长度减1.
3. 数组中的默认值:byte,short,int默认为0,long默认为0L,float默认为0.0F,double默认为0.0,char默认为’\u0000’,boolean默认为false。
4. 引用数据类型默认为null。
5. 数组的长度确定后不能改变。
6. 数组的长度可以为0,但不能为负数,否则运行时发生异常。
7. 通过数组的.length属性,获得数组的长度。
Java的内存分配
A:栈 存储局部变量
B:堆 存储所有new出来的
C:方法区(面向对象部分详细讲解)
D:本地方法区(系统相关)
E:寄存器(CPU使用)
注意:
a:局部变量 在方法定义中或者方法声明上定义的变量。
b:栈内存和堆内存的区别
栈:数据使用完毕,就消失。
堆:1)每一个new出来的东西都有地址。
2)每一个变量都有默认值。
3)数据使用完毕后,在垃圾回收器空闲的时候回收。
数组与循环
foreach循环:从JDK1.5开始出现。
a) 作用:遍历集合。
b) 格式:
1 | for(数据类型 变量名 :集合名){ |
c) 通常用于从集合中取数据。
命令行参数
a) 格式:java 类名 命令行参数
b) 命令行参数由main()中参数String[]数组接收。
c) 命令行参数以空格作为分隔的标记。
二维数组
元素是一维数组的数组。
格式:
1 | A:数据类型[][] 数组名 = new 数据类型[m][n]; // m:表示这个二维数组有多少个一维数组。n:表示每一个一维数组的元素有多少个。 |
注意下面定义的区别:
1 | int x; |
案例:
A:二维数组的遍历
B:二维数组的求和
1 | class ArrayTest { |
C:杨辉三角形(行数可以键盘录入)
1 | /** |
Java中只有值传递
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数