一.Java程序基础
1.Java程序基本结构
Java版HelloWorld
public class Hello{
public static void main(String[] args){
System.out.println("Hello,world!")
}
}
Java程序的基本单位为class
,此代码中class
名字就是Hello
,class前面的public为访问修饰符。
类名要求:
- 类名必须以英文字母开头,后接字母,数字和下划线的组合
- 通常以大写字母开头
- 如果名字是由多个单词组成,每个单词的首字母大写
命名规范的示例:
- Hello
- NoteBook
在class内部可以定义多种方法(method):
public class Hello {
public static void main(String[] args) { // 方法名是main
// 方法代码...
} // 方法定义结束
}
这里方法名为main,返回值为void,public等修饰符也可以修饰方法,
Java入口程序规定的方法必须是静态方法,方法名必须为main
,括号内的参数必须是String数组。
方法名与类名相似,但是规则要求首字母小写。
示例:
- main
- goodNight
- play
方法内部的语句为真正的执行代码,语句和注释的相关使用与c语言相似,在这里不再赘述。
2.变量和数据类型
Java中的变量分为两种:基本类型的变量和引用类型的变量
基本类型的变量是“持有”某个数值,引用类型的变量是“指向”某个对象。
基本数据类型(与c相似)
- 整数类型:byte,short,int,long
- 浮点数类型:float,double
- 字符类型:char
- 布尔类型:boolean
注意:
- 对于
float
类型,需要加上f
后缀。 char
类型使用单引号'
,且仅有一个字符,要和双引号"
的字符串类型区分开。
引用类型
除了基本类型,剩下都是引用类型,例如String
。
常量
加上final
修饰符,变量就变成了常量:
final double PI=3.1415926//PI变为常量
常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。
根据习惯,常量名通常全部大写
var关键字
有些时候,类型的名字太长,写起来比较麻烦。例如:
StringBuilder sb = new StringBuilder();
这个时候,如果想省略变量类型,可以使用var
关键字:
var sb = new StringBuilder();
编译器会根据赋值语句自动推断出变量sb
的类型是StringBuilder
。对编译器来说,语句:
var sb = new StringBuilder();
实际上会自动变成:
StringBuilder sb = new StringBuilder();
因此,使用var
定义变量,仅仅是少写了变量类型而已。
变量的作用范围
规则同c。
定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名。
运算优先级
在Java的计算表达式中,运算优先级从高到低依次是:
()
!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
关系运算符的优先级从高到低依次是:
!
>
,>=
,<
,<=
==
,!=
&&
||
通常加括号保证运算的优先级即可。
浮点数运算注意事项
需要特别注意,在一个复杂的四则运算中,两个整数的运算不会出现自动提升的情况。例如:
double d = 1.2 + 24 / 5; // 5.2
计算结果为5.2
,原因是编译器计算24 / 5
这个子表达式时,按两个整数进行运算,结果仍为整数4
。
布尔运算注意事项
布尔运算的一个重要特点是短路运算。如果一个布尔运算的表达式能提前确定结果,则后续的计算不再执行,直接返回结果。
因为false && x
的结果总是false
,无论x
是true
还是false
,因此,与运算在确定第一个值为false
后,不再继续计算,而是直接返回false
。
字符和字符串
字符类型与c相似,不同的地方在Unicode编码,比如使用转义字符\u
+Unicode编码来表示一个字符:
// 注意是十六进制:
char c3 = '\u0041'; // 'A',因为十六进制0041 = 十进制65
char c4 = '\u4e2d'; // '中',因为十六进制4e2d = 十进制20013
字符串类型为本次Java学习之旅的重点,因为大创的关键就是字符串处理。
字符串类型String
是引用类型,我们用双引号"..."
表示字符串。
String s = ""; // 空字符串,包含0个字符
String s1 = "A"; // 包含一个字符
String s2 = "ABC"; // 包含3个字符
String s3 = "中文 ABC"; // 包含6个字符,其中有一个空格
如果需要表示"
,可以借助转义字符。
String s = "abc\"xyz"; // 包含7个字符: a, b, c, ", x, y, z
String s = "abc\\xyz"; // 包含7个字符: a, b, c, \, x, y, z
常见的转义字符包括:
\"
表示字符"
\'
表示字符'
\\
表示字符\
\n
表示换行符\r
表示回车符\t
表示Tab\u####
表示一个Unicode编码的字符
例如:
String s = "ABC\n\u4e2d\u6587"; // 包含6个字符: A, B, C, 换行符, 中, 文
字符串连接
Java的编译器对字符串做了特殊照顾,可以使用+
连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。例如:
public class Main {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "world";
String s = s1 + " " + s2 + "!";
System.out.println(s);
}
}
//输出为Hello world!
如果用+
连接字符串和其他数据类型,会将其他数据类型先自动转型为字符串,再连接:
public class Main {
public static void main(String[] args) {
int age = 25;
String s = "age is " + age;
System.out.println(s);
}
}
输出为age is 25
多行字符串
从Java 13开始,字符串可以用"""..."""
表示多行字符串。例如:
public class Main {
public static void main(String[] args) {
String s = """
SELECT * FROM
users
WHERE id > 100
ORDER BY name DESC
""";
System.out.println(s);
}
}
/*输出为
SELECT * FROM
users
WHERE id > 100
ORDER BY name DESC
*/
上述多行字符串实际上是5行,在最后一个DESC
后面还有一个\n
。如果我们不想在字符串末尾加一个\n
需要在最后改成 ORDER BY name DESC""";
。
还需要注意到,多行字符串前面共同的空格会被去掉,即:
String s = """
...........SELECT * FROM
........... users
...........WHERE id > 100
...........ORDER BY name DESC
...........""";
如果多行字符串的排版不规则,那么,去掉的空格就会变成这样:
String s = """
......... SELECT * FROM
......... users
.........WHERE id > 100
......... ORDER BY name DESC
......... """;
即总是以最短的行首空格为基准。
不可变特性
public class Main {
public static void main(String[] args) {
String s = "hello";
System.out.println(s); // 显示 hello
s = "world";
System.out.println(s); // 显示 world
}
}
/*输出
hello
world
*/
在这里,字符串s
其实没有变,变的是s
的指向,和指针相似,在JVM虚拟机中根据执行顺序依次创建了hello
和world
,而s
是负责指向这两个字符,当执行到String s = "hello"
时,指向hello
,当执行到s = "world";
时,指向world
。也就是说,字符串"hello"
还在,但是s
指向变了。
public class Main {
public static void main(String[] args) {
String s = "hello";
String t = s;
s = "world";
System.out.println(t); // t是"hello"还是"world"?
}
}
//输出为:hello
空值null
引用类型的变量可以指向一个空值null
,它表示不存在,即该变量不指向任何对象。例如:
String s1 = null; // s1是null
String s2; // 没有赋初值值,s2也是null
String s3 = s1; // s3也是null
String s4 = ""; // s4指向空字符串,不是null
注意要区分空值null
和空字符串""
,空字符串是一个有效的字符串对象,它不等于null
。
数组类型
定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[]
。和单个基本类型变量不同,数组变量初始化必须使用new int[5]
表示创建一个可容纳5个int
元素的数组。
Java的数组特点:
- 数组所有元素初始化为默认值,整型都是
0
,浮点型是0.0
,布尔型是false
; - 数组一旦创建后,大小就不可改变。
可以用数组变量.length
获取数组大小:
public class Main {
public static void main(String[] args) {
// 5位同学的成绩:
int[] ns = new int[5];
System.out.println(ns.length); // 5
}
}
可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推算数组大小。例如:
public class Main {
public static void main(String[] args) {
// 5位同学的成绩:
int[] ns = new int[] { 68, 79, 91, 85, 62 };
System.out.println(ns.length); // 编译器自动推算数组大小为5
}
}
字符串数组
public class Main {
public static void main(String[] args) {
String[] names = {"ABC", "XYZ", "zoo"};
String s = names[1];
names[1] = "cat";
System.out.println(s); // s是"XYZ"还是"cat"?
}
}
//输出:XYZ
二.流程控制
1.输入与输出
输出
输出常用的为System.out.println()
,这里的println
为print line的缩写,表示输出并换行,如果不想换行,可以使用print()
。
public class Main {
public static void main(String[] args) {
System.out.print("A,");
System.out.print("B,");
System.out.print("C.");
System.out.println();
System.out.println("END");
}
}
/*输出:
A,B,C.
END
*/
Java的格式化功能提供了多种占位符,可以把各种数据类型“格式化”成指定的字符串:
占位符 | 说明 |
---|---|
%d | 格式化输出整数 |
%x | 格式化输出十六进制整数 |
%f | 格式化输出浮点数 |
%e | 格式化输出科学计数法表示的浮点数 |
%s | 格式化字符串 |
注意,由于%表示占位符,因此,连续两个%%表示一个%字符本身。
输入
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("Input your name: "); // 打印提示
String name = scanner.nextLine(); // 读取一行输入并获取字符串
System.out.print("Input your age: "); // 打印提示
int age = scanner.nextInt(); // 读取一行输入并获取整数
System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
}
}
首先,我们通过import
语句导入java.util.Scanner
,import
是导入某个类的语句,必须放到Java源代码的开头。
然后,创建Scanner
对象并传入System.in
。
有了Scanner
对象后,要读取用户输入的字符串,使用scanner.nextLine()
,要读取用户输入的整数,使用scanner.nextInt()
。Scanner
会自动转换数据类型,因此不必手动转换。
2.if判断
引用类型判断内容相等要使用equals()
,注意避免NullPointerException
。
其余同c,不再赘述。
3.switch多重选择
保证break
和default
的存在
编译检查
使用IDE时,可以自动检查是否漏写了break
语句和default
语句,方法是打开IDE的编译检查。
在Eclipse中,选择Preferences
- Java
- Compiler
- Errors/Warnings
- Potential programming problems
,将以下检查标记为Warning:
- 'switch' is missing 'default' case
- 'switch' case fall-through
在Idea中,选择Preferences
- Editor
- Inspections
- Java
- Control flow issues
,将以下检查标记为Warning:
- Fallthrough in 'switch' statement
- 'switch' statement without 'default' branch
当switch
语句存在问题时,即可在IDE中获得警告提示。
4.循环
while
、do while
、for
三种基本类型。
在Java中还提供了另一种for each
循环,它可以更简单地遍历数组:
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
}
}
/*输出:
1
4
9
16
25
*/
5.break和continue
break
跳出最近的一层循环;
continue
提前结束当前循环,再执行下一次循环。
1 条评论
凡凡这也太巨了