前言
学习一门语言,快速入门是给我们增加学习信心的法门。如果门槛都跨不进去,学习就是不可能的事。学习能力实际上体现的是一个人跳出舒适圈的意愿程度。
简介
Java程序必须运行在JVM之上,我们必须安装jdk,此时我们实验的环境是jdk13。
程序基础
java程序基本结构
Java是面向对象的语言,一个程序的基本单位就是class。
类名要求:
- 类名必须以英文字母开头,后接字母,数字和下划线的组合
- 习惯以大写字母开头
在class内部,可以定义若干方法(method)。方法名也有命名规则,命名和class一样,但是首字母小写。
Java入口程序规定的方法必须是静态方法,方法名必须为main,括号内的参数必须是String数组。
在方法内部,语句才是真正的执行代码。Java的每一行语句必须以分号结束
举例:
| 1 | public class Hello { //类名是Hello | 
变量和数据类型
变量
- 在Java中,变量必须先定义后使用,在定义变量的时候,可以给它一个初始值。不写初始值,就相当于给它指定了默认值。默认值总是0。
- 变量的一个重要特点是可以重新赋值。
- 变量不但可以重新赋值,还可以赋值给其他变量。
数据类型
- 基本数据类型
 基本数据类型是CPU可以直接进行运算的类型。Java定义了以下几种基本数据类型:
- 整数类型:byte,short,int,long
- 浮点数类型:float,double
- 字符类型:char- char类型使用单引号',且仅有一个字符
 
- char类型使用单引号
- 布尔类型:boolean

- 常量
- 定义变量的时候,如果加上final修饰符,这个变量就变成了常量。
- 常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。
- 常量的作用是用有意义的变量名来避免魔术数字(Magic number)。
- 常量名通常全部大写。
- var关键字
- 如果想省略变量类型,可以使用var关键字。
举例:
| 1 | StringBuilder sb = new StringBuilder(); | 
等价于
| 1 | var sb = new StringBuilder(); | 
数学运算(略)
不想把重点放在数学计算上面,主要是需要学习程序的逻辑。
布尔运算
主要学习短路运算和三元运算符。
- 短路运算
 短路运算的原理就是,如果A是true,那么不会判断B是不是true,A&&B的结果直接返回true。
- 三元运算符
 原理是:如果b是true,b?x:y返回的值是x,否则返回y。其实就是if-else的简化写法。
字符和字符串
字符和字符串的区别是什么?
- 字符是char,它是基本数据类型。- 字符只表示一个字符,用'引起来。
 
- 字符只表示一个字符,用
- 字符串是String,它是引用类型。- 字符串可以表示0~n个字符,用"引起来。
- 如果是多行字符串,可以用"""引起来,避免写换行符。
- 多个字符串可以使用+拼接。
 
- 字符串可以表示0~n个字符,用
附加知识点:空值nullnull其实就是指不存在的东西。
- 把null赋值给一个变量,那么这个变量是null。
- 不给变量赋初值,这个变量也是null。
- 把一个null变量赋值给另一个变量,这另一个变量也是null。
- 但是空字符串不等于null。
 打个绕口的比喻:我把没有给你,你也是没有。我拿一张白纸给你,那么你也有了一张白纸,尽管纸上什么也没有,但你不是没有。没有这个东西,不管怎么传递,还是没有,不会无中生有。
 举例:1 
 2
 3
 4String s1 = null; // s1是null 
 String s2; // 没有赋初值,s2也是null
 String s3 = s1; // s3也是null
 String s4 = ""; // s4指向空字符串,不是null
数组类型
定义一个数组类型的变量,使用数组类型类型[],例如,int[]。和单个基本类型变量不同,数组变量初始化必须使用new int[5]表示创建一个可容纳5个int元素的数组。
Java的数组有几个特点:
- 数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false;
- 数组一旦创建后,大小就不可改变。
- 要访问数组中的某一个元素,需要使用索引。数组索引从0开始,例如,5个元素的数组,索引范围是0~4。
- 可以修改数组中的某一个元素,使用赋值语句,例如,ns[1] = 79;。
- 可以用数组变量.length获取数组大小。
- 数组是引用类型,在使用索引访问数组元素时,如果索引超出范围,运行时将报错。
- 也可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推算数组大小。
举例:
| 1 | public class Main { | 
引申学习:字符串数组
| 1 | public class Main { | 
这段代码的运行结果是"XYZ",说明的是java里面赋值是一种类似指针的概念。names[1]的值指向了s这个变量,之后又把"cat"指向names[1]这个变量。只要指向关系没有改变,变量的 值就不会发生变化。
流程控制
输入和输出
输出的方法比输入的方法简单。先看输出。
- 输出
- println- println意思是- printline,它会帮我们自动输出换行符。
- print
 普通输出,不会自动输出换行符。
- printf- f的意思是- format,就是格式化输出的意思。这里和以前学过的C语言的printf用法就差不多的。不细说,需要用的时候查资料。
- 输入
 首先是需要引入java.util.Scanner这个java模块。
 用法:
- 创建Scanner对象。
- 打印输入提示信息:提示用户需要输入的数据类型是什么。
- 用户输入信息:可能是字符串或者整数。
- 读取用户输入的信息并获取字符串或者整数。
 举例:1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12import 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); // 格式化输出
 }
 }if判断逻辑很简单,如果……,就……;否则,就……。通常用到的就是这样的逻辑判断。关键点在于判断条件的设置方法。
 这里有个特殊的用法,判断引用类型(比如字符串String、数组就是引用类型)的变量是否相等,要使用equals()方法。
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13public class Main { 
 public static void main(String[] args) {
 String s1 = "hello";
 String s2 = "HELLO".toLowerCase();
 System.out.println(s1);
 System.out.println(s2);
 if (s1.equals(s2)) {
 System.out.println("s1 equals s2");
 } else {
 System.out.println("s1 not equals s2");
 }
 }
 } 
 引申学习:.toLowerCase()是String的一个方法,可以将字符串内容全部转换为小写字符。
switch多重选择
java13之后使用的语法和以前版本不同,我分成了老语法和新语法。人要与时俱进,老语法了解一下,要熟练应用新语法。
据我有限的知识储备,老语法和C语言中的switch用法差不多,和VHDL语法也差不多(还是学过VHDL语法的一点皮毛~),看来编程语法具有许多共通性。
- 老语法
 switch语句里面的每一个case都要搭配break使用。
 举例:switch语句还可以匹配字符串。字符串匹配时,是比较“内容相等”。1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19public class Main { 
 public static void main(String[] args) {
 int option = 99;
 switch (option) {
 case 1:
 System.out.println("Selected 1");
 break;
 case 2:
 System.out.println("Selected 2");
 break;
 case 3:
 System.out.println("Selected 3");
 break;
 default:
 System.out.println("Not selected");
 break;
 }
 }
 }
 举例:1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19public class Main { 
 public static void main(String[] args) {
 String fruit = "apple";
 switch (fruit) {
 case "apple":
 System.out.println("Selected apple");
 break;
 case "pear":
 System.out.println("Selected pear");
 break;
 case "mango":
 System.out.println("Selected mango");
 break;
 default:
 System.out.println("No fruit selected");
 break;
 }
 }
 }
- 新语法
 新的语法简洁许多,不用担心忘记写break。并且case里面可以直接使用yield返回结果(python语法里面也有yield的用法)。
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15public class Main { 
 public static void main(String[] args) {
 String fruit = "orange";
 int opt = switch (fruit) {
 case "apple" -> 1;
 case "pear", "mango" -> 2;
 default -> {
 int code = fruit.hashCode(); //对字符串做hash
 System.out.println(code); //code的值
 yield code; // switch语句返回值
 }
 };
 System.out.println("opt = " + opt); //yield返回的值就赋值给了opt
 }
 } 
 引申学习:.hashCode()是String的一个方法,表示对字符串做hash。
while循环和do while循环
这和C语言中的概念也是差不多的,不细说。
while循环和do while循环的本质区别就是:
- while循环先判断条件,再循环。循环体可能不执行。
- do while循环先循环再判断。循环体至少执行1次。
 初高中的时候,数学老师讲过的那两个拗口的中文解释:当型循环和直到型循环分别对应的就是while循环和do while循环。
for循环
原来学C语言的时候,把这个for循环是搞昏了的,计数器到底怎么算,一直没搞清。主要是老师讲解的时候,注入了太多数学元素,而我对数字不太感冒,形不成感性认知,也就理解不清楚。现在站在一个稍微宏观的视角来理解,似乎也不难。
以这个例子(对1到100进行求和)来理解:
| 1 | public class Main { | 
运行结果:
for循环部分,其实就是限定这个循环体的循环次数。从i=1开始,先判断i是否满足条件i<=100,如果满足,就进入循环体,循环结束后,计数器加1。继续判断现在的i是否满足条件i<=100,如果满足,就进入循环体……
发现了没有,我描述中的重复部分,就是在执行循环。这就是编程的伟大之处,它给我们节省不少口水和文字。
- 特殊用法for each
 这是java中的一个特殊用法,用来遍历数组。
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8public class Main { 
 public static void main(String[] args) {
 int[] ns = { 1, 4, 9, 16, 25 };
 for (int n : ns) {
 System.out.println(n);
 }
 }
 } 
 这里的for (int n : ns)意思就是,遍历数组ns中的每一个元素n。但是,for each循环无法指定遍历顺序,也无法获取数组的索引。
break和continue
在C语言和VHDL语言中,都学过这两个用法:break、continue。可以用在while循环和for循环中。break就是戛然而止,就像坐热气球突然把气球炸了。而continue就像刹车,拉手刹之后,车还会滑行一段。
数组操作
遍历数组
用for循环和for each循环可以实现数组的遍历。
- for循环遍历数组
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8
 9public class Main { 
 public static void main(String[] args) {
 int[] ns = { 1, 4, 9, 16, 25 };
 for (int i=0; i<ns.length; i++) {
 int n = ns[i];
 System.out.println(n);
 }
 }
 } 
- for each循环遍历数组
 前面学习for each循环的时候了解过,不赘述于此。
- 打印数组元素的妙方Arrays.toString()
 我们可以直接使用Arrays.toString()这个方法将数组里面的每个元素打印出来,不必使用循环遍历数组。前提是我们要事先引入模块java.util.Arrays才可以使用这个方法。
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8import java.util.Arrays; 
 public class Main {
 public static void main(String[] args) {
 int[] ns = { 1, 1, 2, 3, 5, 8 };
 System.out.println(Arrays.toString(ns));
 }
 } 数组排序冒泡法可以对数组排序,但是鉴于本人对于数字的想象力有限,就不和冒泡法死磕了。java内置了排序方法Arrays.sort()可以帮助我们排序,前提也是要导入模块java.util.Arrays。
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8
 9import java.util.Arrays; 
 public class Main {
 public static void main(String[] args) {
 int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
 Arrays.sort(ns);
 System.out.println(Arrays.toString(ns));
 }
 } 
 对数组排序实际上修改了数组本身。多维数组学会魔方之后,这个问题好像没有那么难了。一维数组的元素就相当于是一个方块,二维数组的元素就是一层魔方,三维数组的元素就是一整个魔方。这么说简单一点,一维数组的单位是块,二维数组的单位是层,三维数组的单位是个。
- 二维数组
 举例:运行结果:1 
 2
 3
 4
 5
 6
 7
 8
 9
 10public class Main { 
 public static void main(String[] args) {
 int[][] ns = {
 { 1, 2, 3, 4 },
 { 5, 6, 7, 8 },
 { 9, 10, 11, 12 }
 };
 System.out.println(ns.length); // 3
 }
 } 
- 三维数组
 略……命令行参数这个命令行参数就是我们在命令行执行java程序时加的参数。
 举例:我们到命令行,先编译这个java文件。1 
 2
 3
 4
 5
 6
 7
 8
 9
 10public class PrintArgs { 
 public static void main(String[] args) {
 for (String arg : args) {
 if ("-version".equals(arg)) {
 System.out.println("v 1.0"); //这句代码的意思是如果用户输入的参数是-version,就打印输出v 1.0
 break;
 }
 }
 }
 }接下来执行程序时带上参数1 javac .\PrintArgs.java -version:1 
 2PS F:\java学习\HelloWorld\src> java PrintArgs -version 
 v 1.0总结快速入门到这里就完成了。把知识先储备在这儿,用的时候不至于陌生。
