Java基础编程
- Java 基础语法
- Java 标识符
- 变量
- 变量的类型
- Java 基本数据类型
- 基本数据类型转换
- 运算符
- 常见运算符
- 运算符的优先级
- 程序流程控制
- 分支语句
- 循环结构
- 常用的循环结构
- 循环的嵌套
- break 和 continue 关键字
- 数组
- 一维数组
- 多维数组的使用
- Arrays 工具类的使用
- 数组中常见的异常
Java 基础语法
Java 标识符
Java 对各种变量、方法和类等要素命名时使用的字符序列称为 标识符,定义合法标识符规则如下:
- 由 26 个英文字母大小写、0-9、_ 或 $ 组成
- 数字不可以开头
- 不可以使用关键字和保留字,但能包含关键字和保留字
- Java 中严格区分大小写,长度无限制
- 标识符不能包含空格
Java 中的名称命名规范如下:
- 包名使用多单词组成时所有字母都小写(
xxxyyyzzz
) - 类名、接口名使用多单词组成时,所有单词的首字母大写(
XxxYyyZzz
) - 变量名、方法名使用多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写(
xxxYyyZzz
) - 常量名的所有字母都要大写,多单词时每个单词用下划线连接(
XXX_YYY_ZZZ
) - 为了提高阅读性,要见名知意
- 不建议使用汉字命名
关于 Java 关键字和保留字
(一)Java 关键字
- 用于定义数据类型的关键字:
class
、interface
、enum
、byte
、short
、int
、long
、float
、double
、char
、boolean
、void
- 用于定义流程控制的关键字:
if
、else
、switch
、case
、default
、while
、do
、for
、break
、continue
、return
- 用于定义访问权限修饰符的关键字:
private
、protected
、public
- 用于定义类、函数、变量修饰符的关键字:
abstract
、final
、static
、synchronized
- 用于定义类与类之间关系的关键字:
extends
、implements
- 用于定义建立实例及引用实例,判断实例的关键字:
new
、this
、super
、instanceof
- 用于异常处理的关键字:
try
、catch
、finally
、throw
、throws
- 用于包的关键字:
package
、import
- 其他修饰符关键字:
native
、strictfp
、transient
、volatile
、assert
- 用于定义数据类型值的字面值:
true
、false
、null
(二)Java 保留字
Java 保留字是现有 Java 版本尚未使用,但以后版本可能会作为关键字使用,命名标识符时要避免使用这些保留字:goto
、const
。
变量
变量的类型
变量是程序中最基本的存储单元(包含变量类型、变量名和存储的值),用于在内存中保存数据。Java 中使用变量时需要注意:
- Java 中每个变量必须先声明后使用
- 使用变量名来访问这块区域的数据
- 变量的作用域在其定义所在的一对
{ }
内 - 变量只有在其作用域内才有效
- 同一个作用域内不能定义重名的变量
对于每一种数据都定义了明确的数据类型(强类型语言),在内存中分配了不同大小的内存空间:
按照变量声明的位置不同,可以分为:成员变量和局部变量:
Java 基本数据类型
整数类型包括:byte
、short
、int
和 long
,使用案例如下:
// byte: -128 ~ 127
byte b = 125;
// short:-2^15 ~ 2^15-1
short s = 126;
// int: 默认的整型,-2^31 ~ 2^31-1
int i = 129;
// long -2^63 ~ 2^63-1
long l = 1258L;
浮点型包括:float
、double
,使用案例如下:
// float 4字节 -3.403E38 ~ 3.403E38
float f = 12.34f;
// double 8字节 -1.798E308 ~ 1.798E308 默认类型
double d = 12.34;
字符型包括:char
,使用案例如下:
/*
* char 可以有三种表现形式
*/
// 1. 单个字符
char c1 = 'a';
// 2. 转义字符
char c2 = '\n';
// 3. Unicode值
char c3 = '\u000f';
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
布尔类型包括:boolean
,一般用来判断逻辑条件:
// 注意:Java 中的 boolean 类型只能取值 true 和 false
boolean isMan = false;
基本数据类型转换
(一)自动类型转换
自动类型转换是指容量小的类型自动转换为容量大的数据类型。数据类型按容量大小排序为:
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
byte
、short
、char
之间不会相互转换,它们三者在计算时首先转换为int
类型boolean
类型不能与其它数据类型运算- 当把任何基本数据类型的值和字符串进行连接运算时(
+
),基本数据类型的值将自动转化为字符串类型
// 全部提升为double类型
byte b1 = 12;
byte b2 = 22;
// 下面的代码报错,因为byte和byte运算也会自动转换为 int
// byte b3 = b1 + b2;
int i = b1 + b2;
(二)强制类型转换
强制类型转换是自动类型转换的逆过程,能够将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符 ()
,但可能造成精度降低或溢出,需要格外要注意。
int number = (int)12.23;
通常字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换成基本类型:
int number = Integer.parseInt("123");
boolean
类型不可以转换为其它的数据类型。
运算符
常见运算符
(一)算术运算符
常见的算术运算符如下:
运算符 | 运算 | 案例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | b=4;-b | -4 |
+ | 加 | 5+5 | 10 |
- | 减 | 6-4 | 2 |
* | 乘 | 3*4 | 12 |
/ | 除 | 5/5 | 1 |
% | 取模(取余) | 7%5 | 2 |
++ | 自增(前):先运算后取值 | a=2;b=++a; | a=3;b=3 |
++ | 自增(后):先取值后运算 | a=2;b=a++; | a=3;b=2 |
– | 自减(前):先运算后取值 | a=2;b=–a; | a=1;b=1 |
– | 自减(后):先取值后运算 | a=2;b=a–; | a=1;b=2 |
+ | 字符串连接 | “He” + “llo” | “Hello” |
算术运算符需要注意的问题
- 如果对负数取模可以把模数的负号忽略不记(如:
5 % -2 = 1
),但被模数是负数则不可忽略(如:-5 % -2 = -1
);此外,取模运算的结果不一定总是整数- 对于除号
/
,它的整数除和小数除是有区别的:整数之间做除法时只保留整数部分而舍弃小数部分+
除字符串相加功能外,还能把非字符串转换成字符串
(二)赋值运算符
赋值运算符是=
,当 =
两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理(支持连续赋值)。此外,赋值运算符还包括下面的扩展赋值运算符:+=
、-=
、*=
、/=
、%=
。
(三)比较运算符(关系运算符)
运算符 | 运算 | 案例 | 结果 |
---|---|---|---|
== | 相等于 | 4==3 | false |
!= | 不等于 | 4!=3 | true |
< | 小于 | 4<3 | false |
> | 大于 | 4>3 | true |
<= | 小于等于 | 4<=3 | false |
>= | 大于等于 | 4>=3 | true |
instanceof | 检查是否是类的对象 | “Hello” instanceof String | true |
注意
- 比较运算符的结果都是
boolean
型- 比较运算符
==
不能误写成=
(四)逻辑运算符
a | b | a&b | a&&b | a|b | a||b | !a | a^b |
---|---|---|---|---|---|---|---|
true | true | true | true | true | true | false | false |
true | false | false | false | true | true | false | true |
false | true | false | false | true | true | true | true |
false | false | false | false | false | false | true | false |
& 和 && 的区别
- 单
&
时,左边无论真假,右边都进行运算- 双
&
时,如果左边为真,右边参与运算;如果左边为假,那么右边不参与运算|
和||
的区别同理,||
表示当左边为真,右边不参与运算。int a = 20; // ++a > 10 不会执行 if (false && ++a > 10) {} System.out.println(a); // 20 // ++a > 10 会执行 if (false & ++a > 10) {} System.out.println(a); // 21 // ++a > 10 不会执行 if (true || ++a > 10) {} System.out.println(a); // 21 // ++a > 10 会执行 if (false | ++a > 10) {} System.out.println(a); // 22
(五)位运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
<< | 左移 | 3 << 2 | 12 |
>> | 右移 | 3 >> 1 | 1 |
>>> | 无符号右移 | 3 >>> 1 | 1 |
& | 与运算 | 6 & 3 | 2 |
| | 或运算 | 6 | 3 | 7 |
^ | 异或运算 | 6 ^ 3 | 5 |
~ | 取反运算 | ~6 | -7 |
位运算符是直接对整数的二进制进行的运算。
运算符 | 说明 |
---|---|
<< | 空位补0,被移除的高位丢弃,空缺位补0 |
>> | 被移位的二进制最高位是0,右移后空缺位补0;最高位是1,空缺位补1 |
>>> | 被移位二进制最高位无论是0或者是1,空缺位都用0补 |
& | 二进制位进行&运算,只有1&1时结果是1,否则是0 |
| | 二进制位进行 | 运算,只有 0|0 时的结果是0,否则是1 |
^ | 相同二进制位进行 ^ 运算,结果是0;不相同二进制位 ^ 运算结果是1 |
~ | 正数取反,各二进制码按补码各位取反;负数取反,各二进制码按补码各位取反 |
(六)三元运算符
三元运算符的格式如下 (条件表达式?表达式1:表达式2)
,当条件表达式为 true
的时候运算结果是表达式 1,否则是表达式2:
int number = 3 > 2 ? 3 : 2;
运算符的优先级
运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如图,上一行运算符总优先于下一行:
程序流程控制
流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。流程控制方式采用结构化程序设计中规定的三种基本流程结构:顺序结构、分支结构和循环结构。
分支语句
(一)if-else
语句
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
int ticket = (int)(Math.random() * 90 + 10);
Scanner sc = new Scanner(System.in);
System.out.print("请输入彩票号码(两位数):");
int number = sc.nextInt();
String tStr = "" + ticket;
String nStr ="" + number;
System.out.println("彩票号码:" + ticket);
System.out.println("输入的号码:" + number);
if (tStr.equals(nStr)) {
System.out.println("奖金 10000 美元");
} else if (tStr.charAt(0) == nStr.charAt(1) && tStr.charAt(1) == nStr.charAt(0) ) {
System.out.println("奖金 3000 美元");
} else if (tStr.charAt(0) == nStr.charAt(0) || tStr.charAt(1) == nStr.charAt(1) ) {
System.out.println("奖金 1000 美元");
} else if (tStr.charAt(0) == nStr.charAt(1) || tStr.charAt(1) == nStr.charAt(0) ) {
System.out.println("奖金 500 美元");
} else {
System.out.println("毛都没有");
}
}
}
if-else 使用说明
- 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
- 语句块只有一条执行语句时,一对
{}
可以省略,但建议保留if-else
语句结构根据需要可以嵌套使用- 当
if-else
结构是多选一时,最后的else
是可选的,根据需要可以省略- 当多个条件是互斥关系时,条件判断语句及执行语句间顺序无所谓;当多个条件是包含关系时,需要遵循 小上大下 / 子上父下
int score = 80; if (score >= 90) { System.out.println("优秀"); } else if (score >= 80) { System.out.println("良好"); } else if (score >= 60) { System.out.println("及格"); } else { System.out.println("不及格"); }
(二)switch-case
语句
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
// 根据用于指定月份,打印该月份所属的季节
// 3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季
Scanner sc = new Scanner(System.in);
System.out.print("请输入月份:");
int month = sc.nextInt();
switch (month) {
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
default:
System.out.println("出入月份不对");
break;
}
}
}
switch-case 使用说明
switch(表达式)
中表达式的值必须是下述几种类型之一:byte
,short
,char
,int
,枚举
,String
case
子句中的值必须是常量,不能是变量名或不确定的表达式值- 同一个
switch
语句,所有case
子句中的常量值互不相同break
语句用来在执行完一个case
分支后使程序跳出switch
语句块。如果没有break
,程序会顺序执行到switch
结尾default
子句是可任选的,其位置也是灵活的,当没有匹配的case
时执行default
switch 和 if 语句的对比
- 如果判断的具体数值不多,而且符合
byte
、short
、char
、int
、String
、枚举
等几种类型,虽然两个语句都可以使用,但建议使用swtich
语句,因为效率稍高- 其他情况,如:对区间判断、对结果为
boolean
类型判断等,则使用if
,因为if
的使用范围更广也就是说,使用
switch-case
的,都可以改写为if-else
,反之不成立。
循环结构
常用的循环结构
循环结构能够实现在某些条件满足的情况下反复执行特定代码的功能,一般循环语句由四个部分组成:初始化部分(init_statement)、循环条件部分(test_exp)、循环体部分(body_statement)和迭代部分(alter_statement)
(一)for
循环
public class HelloWorld {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
sum += i;
}
}
System.out.println("100 以内的偶数的和是:" + sum);
}
}
(二)while
循环
public class HelloWorld {
public static void main(String[] args) {
int sum = 0;
int i = 0;
while (i < 100) {
if (i % 2 == 0) {
sum += i;
}
i++;
}
System.out.println("100 以内的偶数的和是:" + sum);
}
}
(三)do-while
循环
public class HelloWorld {
public static void main(String[] args) {
int sum = 0;
int i = 0;
do {
if (i % 2 == 0) {
sum += i;
}
i++;
} while (i < 100);
System.out.println("100 以内的偶数的和是:" + sum);
}
}
循环的嵌套
循环是可以嵌套的,将一个循环放在另一个循环体内就形成了嵌套循环:
public class HelloWorld {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + (i * j) + "\t");
}
System.out.println();
}
}
}
break 和 continue 关键字
break
语句用于终止某个语句块的执行:
public class HelloWorld {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 10; j++) {
if (j % 2 == 0) {
System.out.print(j + "\t");
break;
}
}
System.out.println();
}
}
}
break
语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块:
public class HelloWorld {
public static void main(String[] args) {
out: for (int i = 0; i < 3; i++) {
for (int j = 0; j < 10; j++) {
if (j % 2 == 0) {
System.out.print(j + "\t");
break out;
}
}
System.out.println();
}
}
}
continue
语句用于跳过其所在循环语句块的一次执行,继续下一次循环(continue
只能使用在循环结构中):
public class HelloWorld {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 10; j++) {
if (j % 2 == 0) {
System.out.print(j + "\t");
continue;
}
}
System.out.println();
}
}
}
continue
语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环:
public class HelloWorld {
public static void main(String[] args) {
out: for (int i = 0; i < 3; i++) {
for (int j = 0; j < 10; j++) {
if (j % 2 == 0) {
System.out.print(j + "\t");
continue out;
}
}
System.out.println();
}
}
}
特殊流程控制语句说明
break
只能用于switch
语句和循环语句中continue
只能用于循环语句中continue
是终止本次循环,break
是终止本层循环break
、continue
之后不能有其他的语句,因为程序永远不会执行其后的语句- 标号语句必须紧接在循环的头部,标号语句不能用在非循环语句的前面
return
并非专门用于结束循环的,它的功能是结束一个方法,当一个方法执行到一个return
语句时,这个方法将被结束- 与
break
和continue
不同的是,return
直接结束整个方法,不管这个return
处于多少层循环之内
数组
数组(Array
)是多个相同类型数据按一定顺序排列的集合,使用一个名字命名,并通过编号的方式对这些数据进行统一管理:
- 数组本身是 引用数据类型,而数组中的元素可以是 任何数据类型(包括:基本数据类型和引用数据类型)
- 创建数组对象会在内存中开辟一整块 连续的空间,而数组名中引用的是这块连续空间的 首地址
- 数组的 长度一旦确定,就不能修改
- 可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快
- 数组的分类:
- 按照维度:一维数组、二维数组、三维数组、…
- 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组
一维数组
数组的初始化方式如下:
// 方法一
int arr1[];
arr1 = new int[3];
// 方法二
int arr2[] = new int[3];
// 方法三
int arr3[] = new int[] {1, 2, 3};
// 方法四
int arr4[] = {1, 2, 3, 4};
arr4[0] = 1;
System.out.println(arr4[0]);
关于数组的几点说明
- 定义并用运算符
new
为之分配空间后,才可以引用数组中的每个元素- 数组元素的引用方式:
数组名[数组元素下标]
- 每个数组都有一个属性
length
指明它的长度(数组一旦初始化,其长度是不可变的)
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化:
- 对于基本数据类型而言,默认初始化值各有不同
- 对于引用数据类型而言,默认初始化值为
null
数组元素类型 | 元素默认初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0 或 ‘\u0000’ |
boolean | false |
引用类型 | null |
多维数组的使用
Java 语言里提供了支持多维数组的语法,但是从数组底层的运行机制来看,其实没有多维数组:
// 方法一
int[][] arr1 = new int[3][2];
// 方法二
int[][] arr2 = new int[3][];
// 方法三
int[][] arr3 = new int[][]{
{3,8,2},
{2,7},
{9,0,1,6}
};
Arrays 工具类的使用
java.util.Arrays
类是操作数组的工具类,包含了用来操作数组(比如:排序和搜索)的各种方法:
方法 | 说明 |
---|---|
boolean equals(int[] a, int[] b) | 判断两个数组是否相等 |
String toString(int[] a) | 输出数组信息 |
void fill(int[] a, int val) | 将指定值填充到数组之中 |
void sort(int[] a) | 对数组进行排序 |
int binarySearch(int[] a, int key) | 对排序后的数组进行二分法检索指定的值 |
public class HelloWorld {
public static void main(String[] args) {
int[] array = {2,4,1,2,7,9,5,6,7};
System.out.println(Arrays.toString(array));
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
数组中常见的异常
// 数组脚标越界异常(ArrayIndexOutOfBoundsException)
// 访问到了数组中的不存在的脚标时发生
int[] arr = new int[2];
System.out.println(arr[2]);
System.out.println(arr[-1]);
// 空指针异常(NullPointerException)
// arr引用没有指向实体,却在操作实体中的元素时。
int[] arr = null;
System.out.println(arr[0]);