J03 Java基础 01:基本语法

概述


JavaSun Microsystems于1995年开发(后被Oracle收购),语法源自C++,最初设计用于交互式电视,随后用于在浏览器中执行代码,是最广泛使用的编程语言之一。


不同语言的工作方式

  • Python

    1
    2
    3
    4
    5
    def factorial(n): 
    if n == 0:
    return 1
    else:
    return n * factorial(n - 1)

    解释器通过读取和执行代码,将指令翻译为二进制代码,并请求处理器执行相应的操作。

  • 编译语言(C, C++)

    1
    2
    3
    4
    5
    6
    int factorial(int n) { 
    if (n == 0)
    return 1;
    else
    return n * factorial(n - 1);
    }

    源代码通过编译器翻译为等效的二进制代码,并直接在处理器上执行。

  • 虚拟机语言(Java)

    1
    2
    3
    4
    5
    6
    7
    8
    public class Math { 
    public static int factorial(int n) {
    if (n == 0)
    return 1;
    else
    return n * factorial(n - 1);
    }
    }

    源代码通过编译器转换为字节码(bytecode)。

    字节码由虚拟机(Virtual Machine)解释并执行

    这种机制使得Java代码具有跨平台的特性,能够在不同的设备和操作系统上运行,只需安装对应的虚拟机即可。

Java基础语法


基本格式


  • 使用// 进行单行注释,使用/*...*/ 进行多行注释。

    1
    2
    3
    // 这是一段注释
    /* 这是一段
    多行注释 */

  • 语句由; 表示结束。

    1
    var r = 10;

  • 在判断条件外使用括号

    1
    while (n != 1)

  • 在块外使用大括号

    1
    2
    3
    if (a > b){
    a = b
    }

  • 主方法入口必须包含在public类中。一个源文件中只有一个public类,源文件的名称应该和 public 类的类名保持一致,一个源文件中可以有多个非public类

    1
    public static void main(String[] args)

IO


输出

1
2
3
4
5
6
7
8
// 定义主类
public class HelloWorld {
// 主方法,程序的入口点
public static void main(String[] args) {
// 打印 "Hello, World" 到控制台
System.out.println("Hello, World");
}
}

输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner; // 导入Scanner类,用于用户输入

public class InputDemo {
public static void main(String[] args) {
String result = getNameAndAge();
System.out.println(result);
}
public static String getNameAndAge() {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("请输入名字:");
String name = scanner.nextLine(); // 读取用户输入的名字
System.out.print("请输入年龄:");
int age = scanner.nextInt(); // 读取用户输入的年龄
// 返回格式化的输出信息
return "名字: " + name + ", 年龄: " + age + "岁";
}
}

在这个例子中,同时展示了ageint隐式转换为String

基础数据类型,Number包装类,Character类


基础数据类型

数据类型 位数 最小值 最大值 默认值 示例 备注
byte 8 -128 (-2^7) 127 (2^7 - 1) 0 byte a = 100 适合处理小范围的整数数据
short 16 -32,768 (-2^15) 32,767 (2^15 - 1) 0 short s = 1000 常用于节省内存空间
int 32 -2,147,483,648 (-2^31) 2,147,483,647 (2^31 - 1) 0 int a = 100000 默认的整型数据类型
long 64 -9,223,372,036,854,775,808 (-2^63) 9,223,372,036,854,775,807 (2^63 - 1) 0L long a = 100000L 注意后缀 L,推荐使用大写避免与 1 混淆
float 32 符合 IEEE 754 标准 符合 IEEE 754 标准 0.0f float f1 = 234.5f 注意后缀 fF
double 64 符合 IEEE 754 标准 符合 IEEE 754 标准 0.0d double d1 = 100.1d 默认浮点数类型,注意后缀 dD
boolean 1 false boolean one = true 仅能为 truefalse
char 16 \u0000 (十进制值 0) \uffff (十进制值 65535) '000' char letter = 'A' 表示单个 Unicode 字符,支持所有国际字符
  • 类型转换
    • 基本要求
        1. 不能对boolean类型进行类型转换。
        1. 不能把对象类型转换成不相关类的对象。
        1. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
        1. 转换过程中可能导致溢出或损失精度,例如:
    • 自动类型转换
      • 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算
      • byte,short,char—> int —> long—> float —> double
  • 强制类型转换
    • (type)value
    1
    2
    int i1 = 123;
    byte b = (byte)i1;

Number包装类

  • 在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类

  • 包装类(Integer、Long、Byte、Double、Float、Short)是抽象类 Number 的子类。

    包装类 基本数据类型
    Boolean boolean
    Byte byte
    Short short
    Integer int
    Long long
    Character char
    Float float
    Double double

    这些类包含了许多便于使用的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class NumberAndMathDemo {
    public static void main(String[] args) {
    // Number 类相关方法
    Integer num = 100;
    System.out.println("1. xxxValue(): " + num.doubleValue()); // 转换为 double
    System.out.println("2. compareTo(): " + num.compareTo(200)); // 比较大小
    System.out.println("3. equals(): " + num.equals(100)); // 判断是否相等
    System.out.println("4. valueOf(): " + Integer.valueOf("123")); // 转换字符串为 Number 对象
    System.out.println("5. toString(): " + num.toString()); // 转换为字符串
    System.out.println("6. parseInt(): " + Integer.parseInt("456")); // 转换字符串为 int
    }
    }
    ---
    1. xxxValue(): 100.0
    2. compareTo(): -1
    3. equals(): true
    4. valueOf(): 123
    5. toString(): 100
    6. parseInt(): 456


Character类

  • Character 类在对象中包装一个基本类型 char 的值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    public class CharacterMethodsDemo {
    public static void main(String[] args) {
    // 示例字符
    char letter = 'A';
    char digit = '5';
    char whitespace = ' ';
    char lowerCaseLetter = 'a';
    char specialChar = '@';
    // 1. isLetter(): 是否是一个字母
    System.out.println("1. isLetter('" + letter + "'): " + Character.isLetter(letter));
    System.out.println("1. isLetter('" + specialChar + "'): " + Character.isLetter(specialChar));

    // 2. isDigit(): 是否是一个数字字符
    System.out.println("2. isDigit('" + digit + "'): " + Character.isDigit(digit));
    System.out.println("2. isDigit('" + letter + "'): " + Character.isDigit(letter));

    // 3. isWhitespace(): 是否是一个空白字符
    System.out.println("3. isWhitespace(' '): " + Character.isWhitespace(whitespace));
    System.out.println("3. isWhitespace('" + letter + "'): " + Character.isWhitespace(letter));

    // 4. isUpperCase(): 是否是大写字母
    System.out.println("4. isUpperCase('" + letter + "'): " + Character.isUpperCase(letter));
    System.out.println("4. isUpperCase('" + lowerCaseLetter + "'): " + Character.isUpperCase(lowerCaseLetter));

    // 5. isLowerCase(): 是否是小写字母
    System.out.println("5. isLowerCase('" + lowerCaseLetter + "'): " + Character.isLowerCase(lowerCaseLetter));
    System.out.println("5. isLowerCase('" + letter + "'): " + Character.isLowerCase(letter));

    // 6. toUpperCase(): 指定字母的大写形式
    System.out.println("6. toUpperCase('" + lowerCaseLetter + "'): " + Character.toUpperCase(lowerCaseLetter));

    // 7. toLowerCase(): 指定字母的小写形式
    System.out.println("7. toLowerCase('" + letter + "'): " + Character.toLowerCase(letter));

    // 8. toString(): 返回字符的字符串形式,字符串的长度仅为1
    System.out.println("8. toString('" + letter + "'): " + Character.toString(letter));
    System.out.println("8. toString('" + digit + "'): " + Character.toString(digit));
    }
    }
    ---
    1. isLetter('A'): true
    1. isLetter('@'): false
    2. isDigit('5'): true
    2. isDigit('A'): false
    3. isWhitespace(' '): true
    3. isWhitespace('A'): false
    4. isUpperCase('A'): true
    4. isUpperCase('a'): false
    5. isLowerCase('a'): true
    5. isLowerCase('A'): false
    6. toUpperCase('a'): A
    7. toLowerCase('A'): a
    8. toString('A'): A
    8. toString('5'): 5


关于包装类,有一些有趣的现象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
public static void main(String[] args) {
Integer a = 127; // 缓存范围内
Integer b = 127; // 缓存范围内
System.out.println(a == b); // true,因为指向相同的缓存对象

Integer c = 128; // 超出缓存范围
Integer d = 128; // 超出缓存范围
System.out.println(c == d); // false,因为创建了新的对象

Integer a = 127; // 自动装箱
int b = 127; // 基本类型
System.out.println(a == b); // true,因为 a 自动拆箱为基本类型 int,再进行值比较

Integer c = 128; // 自动装箱
int d = 128; // 基本类型
System.out.println(c == d); // true,因为 c 自动拆箱为基本类型 int,再进行值比较

Integer a = new Integer(127); // 创建新的 Integer 对象
Integer b = new Integer(127); // 创建新的 Integer 对象
System.out.println(a == b); // false,因为是两个不同的对象
}
}

Java 对于 Integer 类型的某些值使用了一个缓存机制,以提升性能。这个缓存范围通常是 -128127

  • 当通过自动装箱(Autoboxing)将基本类型 int 转换为 Integer 对象时,若值在缓存范围内,则会使用缓存中的对象。
  • 若超出缓存范围,则会创建新的 Integer 对象。

String类和StringBuffer / StringBuilder 类


在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串

创建字符串

  • String str = "Runoob";
  • String str2=new String("Runoob");
    • String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上
  • char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'}; String helloString = new String(helloArray);
  • 字符串在创建之后不能更改,如需要可以更改的字符串,StringBuffer 和 StringBuilder 类

格式化字符串

  • printf方法

    1
    2
    3
    4
    System.out.printf("浮点型变量的值为 " +
    "%f, 整型变量的值为 " +
    " %d, 字符串变量的值为 " +
    "is %s", floatVar, intVar, stringVar);

  • format方法

    1
    2
    3
    4
    5
    String fs;
    fs = String.format("浮点型变量的值为 " +
    "%f, 整型变量的值为 " +
    " %d, 字符串变量的值为 " +
    " %s", floatVar, intVar, stringVar)

常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public class StringMethodsDemo {
public static void main(String[] args) {
// 示例字符串
String str1 = "Hello, World!";
String str2 = "hello, world!";
String str3 = " Java Programming ";
String str4 = "";
// 1. length(): 返回字符串的长度
System.out.println("1. length(): " + str1.length());
// 2. charAt(): 返回指定索引处的字符
System.out.println("2. charAt(7): " + str1.charAt(7));
// 3. equals(): 判断字符串是否相等
System.out.println("3. equals(str2): " + str1.equals(str2));
// 4. equalsIgnoreCase(): 忽略大小写比较
System.out.println("4. equalsIgnoreCase(str2): " + str1.equalsIgnoreCase(str2));
// 5. compareTo(): 按字典顺序比较字符串
System.out.println("5. compareTo(str2): " + str1.compareTo(str2));
// 6. contains(): 检查字符串是否包含子字符串
System.out.println("6. contains(\"World\"): " + str1.contains("World"));
// 7. startsWith(): 检查字符串是否以指定前缀开头
System.out.println("7. startsWith(\"Hello\"): " + str1.startsWith("Hello"));
// 8. endsWith(): 检查字符串是否以指定后缀结尾
System.out.println("8. endsWith(\"!\"): " + str1.endsWith("!"));
// 9. indexOf(): 查找子字符串第一次出现的位置
System.out.println("9. indexOf(\"o\"): " + str1.indexOf("o"));
// 10. lastIndexOf(): 查找子字符串最后一次出现的位置
System.out.println("10. lastIndexOf(\"o\"): " + str1.lastIndexOf("o"));
// 11. toUpperCase(): 转换为大写
System.out.println("11. toUpperCase(): " + str1.toUpperCase());
// 12. toLowerCase(): 转换为小写
System.out.println("12. toLowerCase(): " + str1.toLowerCase());
// 13. trim(): 去掉字符串两端的空白
System.out.println("13. trim(): \"" + str3.trim() + "\"");
// 14. isEmpty(): 检查字符串是否为空
System.out.println("14. isEmpty(): " + str4.isEmpty());
// 15. substring(): 截取字符串
System.out.println("15. substring(7): " + str1.substring(7));
System.out.println("15. substring(0, 5): " + str1.substring(0, 5));
// 16. replace(): 替换子字符串
System.out.println("16. replace(\"World\", \"Java\"): " + str1.replace("World", "Java"));
// 17. split(): 根据指定分隔符分割字符串
String[] words = str1.split(", ");
System.out.println("17. split(\", \"): ");
for (String word : words) {
System.out.println(word);
}
// 18. join(): 将多个字符串组合成一个字符串
String joinedString = String.join(" - ", "Java", "is", "fun");
System.out.println("18. String.join(): " + joinedString);
// 19. valueOf(): 将其他类型转换为字符串
int number = 100;
System.out.println("19. String.valueOf(100): " + String.valueOf(number));
}
}
---
1. length(): 13
2. charAt(7): W
3. equals(str2): false
4. equalsIgnoreCase(str2): true
5. compareTo(str2): -32
6. contains("World"): true
7. startsWith("Hello"): true
8. endsWith("!"): true
9. indexOf("o"): 4
10. lastIndexOf("o"): 8
11. toUpperCase(): HELLO, WORLD!
12. toLowerCase(): hello, world!
13. trim(): "Java Programming"
14. isEmpty(): true
15. substring(7): World!
15. substring(0, 5): Hello
16. replace("World", "Java"): Hello, Java!
17. split(", "):
Hello
World!
18. String.join(): Java - is - fun
19. String.valueOf(100): 100

可修改的字符串:StringBuffer / StringBuilder

String在实现之后是不可修改的,如果希望使用可修改的字符串,需要使用StringBuffer或StringBuilder类。StringBuilder不是线程安全的,但具备速度优势。两者有通用的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class StringBuilderDemo {
public static void main(String[] args) {
// 创建一个 StringBuilder 对象
StringBuilder sb = new StringBuilder("Hello");
// 1. append(String s): 将指定的字符串追加到此字符序列
sb.append(", World!");
System.out.println("1. append(): " + sb);
// 2. reverse(): 将此字符序列用其反转形式取代
sb.reverse();
System.out.println("2. reverse(): " + sb);
sb.reverse(); // 恢复原始顺序
// 3. delete(int start, int end): 移除此序列的子字符串中的字符
sb.delete(5, 12);
System.out.println("3. delete(5, 12): " + sb);
// 4. insert(int offset, int i): 将 int 参数的字符串表示形式插入此序列中
sb.insert(5, 123);
System.out.println("4. insert(int offset, int i): " + sb);
// 5. insert(int offset, String str): 将字符串插入此序列中
sb.insert(5, ", Java");
System.out.println("5. insert(int offset, String str): " + sb);
// 6. replace(int start, int end, String str): 使用给定 String 替换此序列的子字符串中的字符
sb.replace(7, 12, "Programming");
System.out.println("6. replace(7, 12, \"Programming\"): " + sb);

}
}
---
1. append(): Hello, World!
2. reverse(): !dlroW ,olleH
3. delete(5, 12): Hello!
4. insert(int offset, int i): Hello123!
5. insert(int offset, String str): Hello, Java123!
6. replace(7, 12, "Programming"): Hello, Programming23!

运算符


  • 算术运算符

    • +,-,*,/,%(取余),++,--
  • 关系运算符

    • ==,!=,>,<,>=,<=
  • 位运算符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    int a = 60; /* 60 = 0011 1100 */
    int b = 13; /* 13 = 0000 1101 */
    c = a & b; /* 12 = 0000 1100 */
    c = a | b; /* 61 = 0011 1101 */
    c = a ^ b; /* 49 = 0011 0001 */
    c = ~a; /*-61 = 1100 0011 */
    c = a << 2; /* 240 = 1111 0000 */
    c = a >> 2; /* 15 = 1111 */
    c = a >>> 2; /* 15 = 0000 1111 */

  • 逻辑运算符

    • &&,||,!
    • 逻辑运算符的短路:boolean b = (a<4)&&(a++<10),假设a = 5,则a<4false,此时运算符被短路,不会进行a++
  • 赋值运算符

    • =,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
  • 三元运算符

    • variable x = (expression) ? value if true : value if false
  • instanceof

    • 检查该对象是否是一个特定类型
    • boolean result = name instanceof String;

数组


数组用来存储固定大小的同类型元素

创建数组

  • arrayRefVar = new dataType[arraySize];
  • dataType[] arrayRefVar = new dataType[arraySize];
  • 也可以使用{}来创建数组:dataType[] arrayRefVar = {value0, value1, ..., valuek};

访问数组

  • 使用[]

数组参数和数组返回值

  • 数组作为参数传递给函数:public static void printArray(int[] array) {}
  • 数组作为返回值:return result;

多维数组

  • String[][] str = new String[3][4];

  • 多维数组可以具有不同长度的列

    1
    2
    3
    String[][] s = new String[2][];
    s[0] = new String[2];
    s[1] = new String[3];

循环,条件和switch


循环

Java中有三种主要的循环结构:while 循环,do…while 循环,for 循环

  • while 循环
1
2
3
4
5
int i = 0;
while (i < 5) {
System.out.println("当前值: " + i);
i++;
}
  • do while 循环

    1
    2
    3
    4
    5
    int i = 0;
    do {
    System.out.println("当前值: " + i);
    i++;
    } while (i < 5);

  • for 循环

    1
    2
    3
    for (int x = 10; x < 20; x++) {
    System.out.println("x 的值: " + x);
    }

  • 增强 for 循环

    1
    2
    3
    4
    int[] numbers = {10, 20, 30, 40};
    for (int num : numbers) {
    System.out.println("当前值: " + num);
    }

循环可以被break,continue控制。


条件

1
2
3
4
5
6
7
8
9
10
int score = 85;
if (score >= 90) {
System.out.println("成绩等级:A");
} else if (score >= 80) {
System.out.println("成绩等级:B");
} else if (score >= 70) {
System.out.println("成绩等级:C");
} else {
System.out.println("成绩等级:D");
}

Switch case

1
2
3
4
5
6
7
8
9
10
11
int number = 2;
switch (number) {
case 1:
System.out.println("数字为 1");
break;
case 2:
System.out.println("数字为 2");
break;
default:
System.out.println("数字未知");
}

方法


定义

1
2
3
4
5
6
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}

重载

  • 创建另一个有相同名字但参数不同的方法
  • 重载的方法必须拥有不同的参数,不能仅仅依据修饰符或者返回类型的不同来重载方法

命令行参数

1
2
3
4
5
6
7
public class CommandLine {
public static void main(String[] args){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}

构造方法和finalize方法

  • 用于初始化和销毁对象,会在类的部分进一步讨论

可变参数

  • 在方法声明中,在指定参数类型后加一个省略号(...)
  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class VarargsExample {
// 定义一个可变参数方法
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num; // 累加所有参数
}
return total;
}

public static void main(String[] args) {
// 调用可变参数方法
System.out.println("和(1, 2, 3): " + sum(1, 2, 3)); // 传递 3 个参数
System.out.println("和(10, 20): " + sum(10, 20)); // 传递 2 个参数
System.out.println("和(无参数): " + sum()); // 不传递参数
}
}
---
和(1, 2, 3): 6
和(10, 20): 30
和(无参数): 0