Function (函数)

基本结构

1
2
3
ReturnType Name(){
...
}

返回值+函数名,括号里放参数,花括号里放代码。

每个Java程序都会有个main函数,main函数是程序的入口点。

1
2
3
void main(){
...
}

但是,函数不是独立存在的,它们总是属于一个类。

Class(类)

类是一个或多个函数的容器。
每个Java程序都有一个Main类

1
2
3
4
5
class Main{
void main(){
...
}
}

花括号之间定义的函数属于这个类,更确切地说,这类函数称为Method(方法)。
因此说方法是类的一部分函数。(Method必须定义在类或对象中)
在Java中,每个类和方法都有访问修饰符(比如public或private),大多数时间我们用public,就像这样

1
2
3
4
5
public class Main{
void main(){
...
}
}

这就是Java程序的主要结构

命名

类的命名:每个单词的首字母大写。
方法的命名:第一个单词首字母小写,后面的单词首字母大写。

HelloWorld

我们将用到System类,使用其中的out字段(打印流),使用其中方法的println。
整体就是

1
2
3
4
5
public class Main{
public static void main(String[] args){
System.out.println("Hello World");
}
}

注意:文件名要和类名一致,这时候这个文件就要命名为Main.Java。

编译和运行

可以直接在VsCode里Run
也可以在Linux里面通过Javac Main.java进行编译,再通过Java Main运行。

变量

int age = 30;之类的,和cpp差不多。
赋值什么的用法也差不多。
同样的,变量名也是要第一个字母小写。

Primitive Type(原始类型)


就比如上面的int age = 30;,可以用byte age = 30;来节省内存。
当我有一个大数字时,我可以使用下划线增强数据的可读性,例如int viewsCount = 123_456_789;
当数字很大,超过了int的存储范围的时候,就要用到long,但是不能写long viewsCount = 3_123_456_789,因为Java会把后面的数字默认当成int型,所以要在数字后面加一个L,大小写不影响,但是小写l很像数字1,建议大写。
类似的,Java会把小数默认为double类型,所以在给float变量赋值的时候,我们要在数字后面加一个F,比如float price = 10.99F
对于Char,使用单引号把字符包裹起来。比如char letter = 'A';
而对于多个字符,使用双引号。
和cpp一样,关键词不可以用于变量的命名。

Reference Type(引用类型)

在处理引用类型的时候,我们需要使用new来分配内存,这点和原始类型不同。
例如:Date now = new Date();
但是不用考虑内存释放,编译器会自己处理好。
并且在使用Date这个类型的时候,还要再头部声明import java.util.Date;,有的软件会在你写出Date时自动帮你补好这句,但是在我的Linux里要自己手动补充。😓
并且我们在下一行输入now.的时候,底下会自动跳出这个类的各个成员,像这样
而原始类型是不会有这些的。
这里的完整代码是这样的

1
2
3
4
5
6
7
import java.util.Date;
public class Main{
public static void main(String[] args){
Date now = new Date();
System.out.println(now);
}
}

就是使用Date来得到现在的时间,就是说,当你创建一个 Date 对象时,它会自动记录当前的日期和时间。
这里的Date是一个类,头部的import java.util.Date;是一个Package(包)。

Primitive VS Reference

在内存管理方面,这两种类型存在非常重要的区别。
比如说,当我们使用原始类型时,像这样

1
2
3
4
5
6
7
8
9
import java.util.Date;
public class Main{
public static void main(String[] args){
byte x = 1;
byte y = x;
x = 2;
System.out.println(y);
}
}

输出结果是 1。
X和Y起初内存是完全独立的,因此改变X也不会改变Y。
但是当我们使用引用类型的时候,就像这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.awt.*;

public class Main {

    public static void main(String[] args) {

        Point point1 = new Point(1, 2);

        Point point2 = point1;

        point1.x = 3;

        System.out.println(point2.x);

    }

}

输出结果是 3。
这是因为在引用类型中,首先环境先分配一点内存来存储这个Point对象,然后我们这里假设这个对象的地址是100,然后再分配一个内存位置,在该位置存储Point的地址。这和原始类型很不一样。
(有点像cpp的指针,但是Java不需要手动释放内存)

因此在这里Point1和Point2引用的是内存中的同一个Point对象,也就是说这两个变量彼此并不独立。也就意味着我随便改一个,另外一个也会一起变化。

String(字符串)

不需要import包,java自带了。
String类其实是引用类型,但是为了简便,可以这样初始化。
例子:

1
2
3
4
public class Main{
public static void main(String[] args){
String message = "Hello World";
System.out.println(message);

我们可以用加号+将两个字符串连接起来,就像String message = “Hello,World” + “!!”;,就会输出Hello,World!!。
并且,String是一个类,同样可以用点访问成员。
比如message.endWith(),来判断字符串是否以一个字符或字符序列结尾。

1
2
3
4
5
public class Main{
public static void main(String[] args){
String message = "Hello World" + "!!";
message.endWith("!!");
System.out.println(message);

输出true。
同理,也有message.startWIth()
message.length(),来查看字符串中有多少个字符。
message.indexOf(),来查看字符串中某个字符的索引,比如“Hello,World!!”中H的索引值为0。(有点类似数组) 如果查找的字符不在字符串中,会输出-1。
message.replace用于替换,比如message.replace("!","*")就是用星号(*)替换感叹号(!)
这段程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {

    public static void main(String[] args) {

        String message = "Hello, World!";

        System.out.println(message.replace("!", "*"));

        System.out.println(message);



    }

}

就会输出
Hello,World*
Hello,World!
因为在Java中字符串是不可改变(Immutable)的,一旦一个 String 对象被创建,它的值就不能被修改。任何看似“修改”字符串的操作(如拼接、替换、大小写转换等),实际上都会创建一个新的 String 对象,而原字符串保持不变。
message.toLowerCase将大写转成小写,
message.toUpperCase将小写转大写。
message.trim(),去掉字符串前后多余的空格,如果message = " Hello,World! ",用System.out.println(message.trim());,就会输出Hello,World!

转义序列

如果我们想让字符串内容为Hello,"World",我们不能直接在双引号内部再放一对双引号,而是使用反斜杠,像这样String message = "Hello,\"World\"";
而当我们想输出反斜杠的时候,我们要在反斜杠前加一个反斜杠,表示转意字符。
比如\\会输出\。
\n用于换行。\t用于制表。

Arrays(数组)

定义一个含有5个元素的数组,int[] numbers = new int[5];
赋值的话和cpp差不多,numbers[0] = 1;,当索引值超过4,Java会报错。
当我们直接System.out.println(numbers)时,会输出一段奇怪的字符串,这是Java基于内存中此对象的地址计算出的字符串。这个字符串对每个数组来说都不同。
想要输出数组中的所有元素,我们可以调用Array类。
首先引用这个类import java.uti.Arrays,接着就可以用Array.toString()得到数组内容了,
最后输出System.out.println(Array.toString(numbers))
运行就可以得到数组内容。
整型数组的话默认为0,布尔型默认为false,字符串型默认为空字符串。
更便利的创建字符串的方式int[] numbers = {2,3,4,5,6};
我们可以通过numbers.length得到字符串长度
例如System.out.println(numbers.length),就会输出5.
我们还可以通过Array.sort(numbers)对数组进行从小到大排序

多维数组

比如说二维数组(两行三列)就是int [][] numbers = new int[2][3];
当我们要输出多维数组的时候,我们就要用到deepToStrign(numbers)
比如这样System.out.println(Arrays.deepToString(numbers));
同样的,花括号也适用。
例如int [][] = {{1,2,3},{4,5,6}}

Constant(常量)

当我们不想改变一个变量的值的时候,在变量种类奇前加上final,就可以保证它是一个常量,例如final float PI = 3.14F,就保证了PI是常量3.14,不会被改变。

Arithmetic Expressions(算数表达式)

加、减、乘、除、取模都是和cpp一样的。
注意:在计算10/3如果想要小数结果,得写成
double num = (double)10 / (double)3;
写成double num = 10 / 3;会输出3.0
(有点烦诶😓)
好吧这样写也可以输出小数double num = 1.0 * 10 / 3;
x++;这种自增和自减也是和cpp一样的。
还有x = x + 2; x += 2;,和cpp都一样。

Order of Operations (执行顺序)

符合基本的数学运算顺序。

Cast(转换)

隐式转换

例如:

1
2
3
short x = 1;
int y = 2 + x;
System.out.println(y);

就会输出3。
有这样的规律byte < short < int < long,存储空间小的可以转化为大的。
只要不丢失数据就可以发生隐式转换。(double转int这种就会丢失。)

显式转换

就比方说丢失数据问所谓了,就可以这样

1
2
3
double x = 1.1;
int y = 2 + (int)x;
System.out.println(y);

就是将x强转成1。
注意:这些都是发生在兼容类型之间的,就是数字只能转数字,不能说字符串转数字。
但是啊但是啊,在java.lang这个包里面,有这些东西可以用来转字符串。
Integer.parseInt()
Short.parseShort()
Float.parseFloat()
诸如此类。
来个例子看看

1
2
3
String x = "1";
int y = 2 + Integer.parseInt(x);
System.out.println(y);

这样输出 3。