Java是一门艺术讲究说学逗唱--Java基础语法
Java是一门艺术,它讲究说学逗唱,一起领略java语法的美
Java 版本概述
在 Java 这门语言体系当中,最基础的部分就是 Java SE 部分,Java 的标准版本。它包括 Java 最基础的一些结构,包括面向对象的一些特性等等,同时它也是 Java 技术基础和核心。在 Java SE 的基础之上,又分为了 Java EE(Java 的企业版),应用于大型企业级应用的开发。Java ME 主要用于嵌入式开发。
-
JVM 是 Java 虚拟机,它也是整个 Java 技术的核心。Java 语言的跨平台归功于 JVM。
-
JDK 是 Java 开发工具包,没有 JDK 就没有办法进行 Java 程序的开发。
-
JRE 是 Java 运行环境,如果我们需要运行一个 Java 程序,就需要安装 JRE。
JDK、JRE 和 JVM 之间的关系:
HelloWorld
public class HelloWorld{ public static void main(String[] args){ System.out.println("HelloWorld!"); }}
Java 中所有的代码都必须包含在 class 中,main
方法是程序的入口,并且 Java 是区分大小写的,如果写成 Main,那么程序将因找不到程序入口而无法运行。使用 public
修饰的 class
名(HelloWorld
)必须和源代码文件名相同。
$ javac HelloWorld.java$ java HelloWorldHelloWorld!
编译源代码:打开命令行,切换到源代码目录。输入 javac HelloWorld.java
,如果程序没有任何提示,并且在同级目录下生成了一个 .class
扩展名的文件,那么说明编译成功,反之编译失败。
变量
在 Java 中,变量需要先声明 (declare) 才能使用。在声明中,需要包括数据类型和变量名称,语法格式与 C++ 相同。例如:
int a = 1;
常量
Java 中的 final
关键字可以用于声明属性(常量),方法和类。当 final
修饰属性时,代表该属性一旦被分配内存空间就必须初始化。在变量前面添加关键字 final
即可声明一个常量。在 Java 编码规范中,要求常量名必须大写。例如:
final double PI = 3.14;
常量也可以先声明,再进行赋值,但只能赋值一次,比如:
final int FINAL_VARIABLE;FINAL_VARIABLE = 100;
数据类型
数据类型
Java 中一共八种基本数据类型,下表列出了基本数据类型的数据范围、存储格式、默认值和包装类型等。
数据类型 | 默认值 | 存储格式 | 数据范围 | 包装类型 |
---|---|---|---|---|
short |
0 | 2 个字节 | -32,768 到 32,767 | Short |
int |
0 | 4 个字节 | -2,147,483,648 到 2,147,483,647 | Integer |
byte |
0 | 1 个字节 | -128 到 127 | Byte |
char |
空 | 2 个字节 | Unicode 的字符范围:\u0000 (即为 0)到 \uffff (即为 65,535) |
Character |
long |
0L 或 0l | 8 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | Long |
float |
0.0F 或 0.0f | 4 个字节 | 32 位 IEEEE-754 单精度范围 | Float |
double |
0.0 或 0.0D(d) | 8 个字节 | 64 位 IEEE-754 双精度范围 | Double |
boolean |
false | 1 位 | true 或 false | Boolean |
整数
byte
、short
、int
、long
四种基本数据类型表示整数,需要注意的是 long
类型,使用 long
修饰的变量需要在数值后面加上 L 或者 l,比如 long num = 1L;
,一般使用大写 L
,为了避免小写 l
与数值 1
混淆。
浮点数
float
和 double
类型表示浮点数,即可以表示小数部分。需要注意的是 float
类型的数值后面需要加上 F
或者 f
,否则会被当成 double
类型处理。double
类型的数值可以加上 D
或 d
,也可以不加。
char 类型
char
类型表示单个字符。需要将字符用单引号括起来char a = 'a';
,char 可以和整数互相转换,如果字符 a
也可以写成char a = 97;
。也可以用十六进制表示char a = '\u0061';
。
boolean 类型
boolean
类型表示真值 true
或者假值 false
,可以使用 1 bit 来存储,但是具体大小没有明确规定。JVM 会在编译时期将 boolean
类型的数据转换为 int
,使用 1 来表示 true
,0 来表示 false
。JVM 支持 boolean
数组,但是是通过读写 byte 数组来实现的。Java 中布尔值不能和整数类型或者其它类型互相转换。
String
Java 中使用 String
类来定义一个字符串,字符串是常量,它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。
String
对象的初始化格式有如下两种:
String s0 = "abc";String s1 = new String("abd");
String
类具有丰富的方法,比如计算字符串的长度、连接字符串、比较字符串、提取字符串等等。
计算字符串长度
length()
方法:
//方法原型public int length(){}
调用方法:字符串标识符.length();
返回一个 int
类型的整数(字符串中字符数,中文字符也是一个字符)。例如:
String s1 = "abc";String s2 = "Java语言";int len1 = s1.length();int len2 = s2.length();
则变量 len1
的值是 3,变量 len2
的值是 6。
字符串比较
equals()
方法,该方法的作用是判断两个字符串对象的内容是否相同。如果相同则返回 true
,否则返回 false
。
equals()
方法比较是从第一字符开始,一个字符一个字符依次比较。
如果想忽略掉大小写关系,可以调用 equalsIgnoreCase()
方法,其用法与 equals()
一致,不过会忽视大小写。而使用 "=="
比较的是两个对象在内存中存储的地址是否一样。例如:
String s1 = "abc";String s2 = new String("abc");boolean b = (s1 == s2);
则变量 b
的值是 false
,因为 s1
对象对应的地址是 "abc"
的地址,而 s2
使用 new
关键字申请新的内存,所以内存地址和 s1
的 "abc"
的地址不一样,所以获得的值是 false
。
字符串连接
字符串连接有两种方法:
- 使用
+
,比如String s = "Hello " + "World!"
。 - 使用
String
类的concat()
方法。
例如:
String s0 = new String("Hello ");String s1 = "World" + "!"; //+号连接String s2 = s0.concat(s1); //concat()方法连接System.out.println(s2);
而且使用 +
进行连接,不仅可以连接字符串,也可以连接其他类型。但是要求进行连接时至少有一个参与连接的内容是字符串类型。
charAt() 方法
charAt()
方法的作用是按照索引值(规定字符串中第一个字符的索引值是 0,第二个字符的索引值是 1,依次类推),获得字符串中的指定字符。例如:
String s = "abc";char c = s.charAt(1);
则变量 c
的值是 'b'
。
字符串常用提取方法
方法 | 返回值 | 功能描述 |
---|---|---|
indexOf(char ch) |
int |
搜索字符 ch 第一次出现的索引 |
indexOf(String value) |
int |
搜索字符串 value 第一次出现的索引 |
lastIndexOf(char ch) |
int |
搜索字符 ch 最后一次出现的索引 |
lastIndexOf(String value) |
int |
搜索字符串 value 最后一次出现的索引 |
substring(int index) |
String |
提取从位置索引开始到结束的字符串 |
substring(int beginindex, int endindex) |
String |
提取 beginindex 和 endindex 之间的字符串部分 |
trim() |
String |
返回一个前后不含任何空格的调用字符串的副本 |
说明:在字符串中,第一个字符的索引为 0,子字符串包含
beginindex
的字符,但不包含endindex
的字符。如果参数只有beginindex
,那么会提取从beginindex
开始到结束的字符。
String Builder
String
是无法被修改的,对 String
的修改,其实是新建了一个 String
对象。StringBuilder
修改字符串的内容,相当于一个存储字符的容器。
初始化格式有以下三种:
# 构造一个不包含任何字符且初始容量为 16 的 StringBuilderStringBuilder a = new StringBuilder();# 构造一个不包含任何字符且容量为 cap 的 StringBuilderStringBuilder b = new StringBuilder(int cap);# 构造一个 StringBuilder,内容初始化为 strStringBuilder c = new StringBuilder(String str);
而第三种方法初始化的容量是初始容量 16 + str
的长度。
StringBuilder 常用方法:
方法 | 返回值 | 功能描述 |
---|---|---|
deleteCharAt(int index) |
StringBuilder |
删除 StringBuilder 中指定位置的 char |
indexOf() |
int |
返回子字符串首次出现在该字符串中的索引 |
capacity() |
int |
返回当前容量 |
charAt(int index) |
char |
返回序列中指定索引的 char 值 |
toString() |
String |
返回序列数据的 String 格式 |
算术运算符
算术运算符用在数学表达式中,主要实现的是算术运算,如常见的加减乘除等。
表格中的例子中,变量 a
的值为 5,变量 b
的值为 3,变量 i
的值为 1:
算术运算符 | 名称 | 描述 | 类型 | 举例 |
---|---|---|---|---|
+ | 加法 | 相加运算符两侧的值 | 双目运算符 | a + b 等于 8 |
- | 减法 | 左操作数减去右操作数 | 双目运算符 | a - b 等于 2 |
* | 乘法 | 相乘操作符两侧的值 | 双目运算符 | a * b 等于 15 |
/ | 除法 | 左操作数除以右操作数 | 双目运算符 | a / b 等于 1 |
% | 取余 | 左操作数除右操作数的余数 | 双目运算符 | a % b 等于 2 |
++ | 自增 | 操作数的值增加 1 | 单目运算符 | ++i(或 i++) 等于 2 |
-- | 自减 | 操作数的值减少 1 | 单目运算符 | --i(或 i--) 等于 0 |
其中,自增(++)和自减(--)运算符有两种写法:前缀(++i,--i)和后缀(i++,i--)。
- 前缀自增自减法(++i,--i):先进行自增或者自减运算,再进行表达式运算。
- 后缀自增自减法(i++,i--):先进行表达式运算,再进行自增或者自减运算
位运算符
Java 定义了位运算符,应用于整数类型 (int
),长整型 (long
),短整型 (short
),字符型 (char
),和字节型 (byte
) 等类型。位运算时先转换为二进制,再按位运算。
表格中的例子中,变量 a
的值为 60(二进制:00111100
),变量 b
的值为 13(二进制:00001101
):
位运算符 | 名称 | 描述 | 举例 |
---|---|---|---|
& | 按位与 | 如果相对应位都是 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
为真(true
),变量 b
为假(false
):
逻辑运算符 | 名称 | 描述 | 类型 | 举例 |
---|---|---|---|---|
&& 或 & | 与 | 当且仅当两个操作数都为真,条件才为真 | 双目运算符 | (a && b) 或 (a & b) 为假 |
|| 或 | | 或 | 两个操作数任何一个为真,条件为真 | 双目运算符 | (a || b) 或 (a | b) 为真 |
! | 非 | 用来反转操作数的逻辑状态。如果条件为真,则逻辑非运算符将得到假 | 单目运算符 | (!a)为假 |
^ | 异或 | 如果两个操作数逻辑相同,则结果为假,否则为真 | 双目运算符 | (a ^ b) 为真 |
&&
与 ||
是具有短路性质,当按优先级顺序计算到当前表达式时,表达式的结果可以确定整个表达式的结果时,便不会继续向后进行判断和计算,而直接返回结果。
关系运算符
关系运算符生成的是一个 boolean
(布尔)结果,它们计算的是操作数的值之间的关系。如果关系成立,结果为 true
(真),否则,结果为 false
(假)。
表格中的例子中,假设变量 a
为 3,变量 b
为 5:
比较运算符 | 名称 | 描述 | 举例 |
---|---|---|---|
== | 等于 | 判断两个操作数的值是否相等,如果相等则条件为真 | (a == b) 为 false |
!= | 不等于 | 判断两个操作数的值是否相等,如果值不相等则条件为真 | (a != b) 为 true |
> | 大于 | 判断左操作数的值是否大于右操作数的值,如果是那么条件为真 | (a > b) 为 false |
< | 小于 | 判断左操作数的值是否小于右操作数的值,如果是那么条件为真 | (a < b) 为 true |
>= | 大于等于 | 判断左操作数的值是否大于或等于右操作数的值,如果是那么条件为真 | (a >= b) 为 false |
<= | 小于等于 | 判断左操作数的值是否小于或等于右操作数的值,如果是那么条件为真 | (a <= b) 为 true |
除了上表列出的二元运算符,Java 还有唯一的一个三目运算符 ?:
。
语法格式:
布尔表达式 ?表达式 1 : 表达式 2;
运算过程:如果布尔表达式的值为 true
,则返回表达式 1的值,否则返回表达式 2的值。
强调:
==
和!=
适用于所有的基本数据类型,其他关系运算符不适用于boolean
,因为boolean
值只有true
和false
,比较没有任何意义。==
和!=
也适用于所有对象,可以比较对象的引用是否相同。
引用:Java 中一切都是对象,但操作的标识符实际是对象的一个引用。
运算符优先级
运算符的优先级不需要特别记忆,比较复杂的表达式一般使用圆括号 ()
分开,提高可读性。
关键字和方法
关键字
Java 的关键字用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名。其中,const
和 goto
这两个关键字在 Java 语言中并没有具体含义。
方法的定义语法:访问修饰符 返回值类型 方法名(参数列表) { 方法体}比如:public void functionName(Object arg) { System.out.println("Hello World.");}
在上面的语法说明中:
- 访问修饰符:代表方法允许被访问的权限范围, 可以是
public
、protected
、private
或者省略(default
) ,其中public
表示该方法可以被其他任何代码调用。- 返回值类型:方法返回值的类型,如果方法不返回任何值,则返回值类型指定为
void
(代表无类型);如果方法具有返回值,则需要指定返回值的类型,并且在方法体中使用return
语句返回值。- 方法名:是方法的名字,必须使用合法的标识符。
- 参数列表:是传递给方法的参数列表,参数可以有多个,多个参数间以逗号隔开,每个参数由参数类型和参数名组成,以空格隔开。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
根据方法是否带参、是否带返回值,可将方法分为四类:
- 无参无返回值方法
- 无参带返回值方法
- 带参无返回值方法
- 带参带返回值方法
当方法定义好之后,需要调用才可以生效,可以通过 main
方法(main
方法是 Java 程序的入口)来调用它。
流程控制
流程控制提供了控制程序步骤的基本手段,主要分为条件语句、循环语句和跳转语句。i
f 语句if 语句是一种判断语句,语法与 C++ 类似。语法:if(条件1){ 代码块1}else if(条件2){ 代码块2}...else { 代码块n}
注:所有的条件语句都是利用条件表达式的真或假来决定执行路径,Java 里不允许将一个数字作为布尔值使用,虽然这在 C 和 C++ 是允许的,如果要在布尔测试里使用一个非布尔值,需要先用一个条件表达式将其转换成布尔值,其他控制语句同理。
switch 语句
需要对选项进行等值判断时使用 switch
语句,语法与 C++ 类似。语法:
switch(表达式){ case 值1: 代码块1 break; case 值2: 代码块2 break; ... default: 默认执行的代码块}
当 switch
后表达式的值和 case
语句后的值相同时,从该位置开始向下执行,直到遇到 break
语句或者 switch
语句块结束;如果没有匹配的 case
语句则执行 default
块的代码。
defualt
块不是必须的,默认为空。- 从 Java 7 开始,可以在
switch
条件判断语句中使用String
对象。 switch
不支持long
、float
、double
,是因为switch
的设计初衷是对那些只有少数几个值的类型进行等值判断,如果值过于复杂,你们还是用if
更加合适。
while 和 do-while 语句
while
语法:
while(条件){ 代码块}
while
的执行过程是先判断,再执行。
- 判断
while
后面的条件是否成立 (true
orfalse
) - 当条件成立时,执行循环内的代码。
do-while
语法:
do{ 代码块}while(条件);
do-while
的执行过程是先执行一次,再循环判断(所以循环内的代码至少会执行一次)。
- 先执行一遍循环操作,然后判断循环条件是否成立。
- 如果条件成立,继续执行
1
、2
,直到循环条件不成立为止。
for 语句
for
语法:
for(循环变量初始化; 循环条件; 循环变量值操作){ 循环操作}
其执行顺序理解方式也与 C++ 相同,无须赘述。
跳转语句
break
关键字经常用在条件和循环语句中,用来跳出循环语句。
continue
关键字的作用是跳过循环体中剩余的语句执行下一次循环。
数组
数组是用于储存多个相同类型数据的集合。数组中的元素都可以通过下标来访问,下标从 0 开始,到数组长度 -1 结束。使用数组前要声明数组。语法:
数据类型[ ] 数组名; //或者: 数据类型 数组名[ ];
声明数组后,需要为数组分配空间,也就是定义多大的数组。
语法:
数组名 = new 数据类型 [ 数组长度 ];
数组长度就是数组最多可存放元素的个数。可以在数组声明的时候初始化数组,或者在声明时就为它分配好空间,这样就不用再为数组分配空间。
Java 中可以将一个数组赋值给另一个数组,如:
int [] a1 = {1,2,3};int [] a2;a2 = a1;
这里只是复制了一个引用,即 a2 和 a1 是相同数组的不同名称。所以当修改 a2 的值时,a1 的值也会变化。
数组遍历:
int [] a = {12, 18, 9, 33, 45, 60};for(int i = 0; i < a.length; i++){ // a.length是获取数组的长度 System.out.println(a[i]); // 注意数组下标从零开始}
注意:
- 数组下标从 0 开始。所以数组的下标范围是 0 至 数组长度 -1。
- 数组不能越界访问,否则会报错。
for 语句在数组内可以使用特殊简化版本,在遍历数组、集合时,foreach 更简单便捷。语法与 C++ 中的 auto
关键字类似。
语法:
for(元素类型 元素变量:遍历对象){ 执行的代码}
二维数组
二维数组也需要声明和分配空间。
语法:
数据类型 [][] 数组名 = new 数据类型[行的个数][列的个数];//或者数据类型 [][] 数组名;数组名 = new 数据类型[行的个数][列的个数];//也可以数据类型 [][] 数组名 = {{第一行值1,第一行值2,...}{第二行值1,第二行值2,...}...}//二维数组的赋值和访问与一维数组类似数组名[行的索引][列的索引] = 值;
用户输入操作
Java 可以使用 java.util
包下的Scanner
类来获取用户的输入。使用 import java.util.Scanner;
即可导入 Scanner。如下示例:
import java.util.Scanner;public class RepeatString { public static void main(String[] args) { Scanner in=new Scanner(System.in); //获取用户输入的一行数据,返回为字符串 String s = in.nextLine(); System.out.println(s); //循环读取String数据,当输入exit时退出循环 while (!in.hasNext("exit")) { System.out.println(in.nextLine()); } //关闭输入 in.close(); }}
除去以上列举的方法,其他方法可以在 API 文档中查询:
Scanner (Java Platform SE 8 )https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
Arrays
Arrays 类包含用于操作数组的各种方法(例如排序和搜索)。还包含一个静态工厂,允许将数组转为 List。
方法 | 描述 |
---|---|
List asList(T... a) |
返回由指定数组构造的 List |
void sort(Object[] a) |
对数组进行排序 |
void fill(Object[] a, Object val) |
为数组的所有元素都赋上相同的值 |
boolean equals(Object[] a, Object[] a2) |
检查两个数组是否相等 |
int binarySearch(Object[] a, Object key) |
对排序后的数组使用二分法查找数据 |