• xianaldai

    本期是Java开发教程系列的第一期,本期主要要向各位介绍Java的基础信息.若你已经了解Java语法基础,并对面向对象编程有一定的体会,可以跳过本期内容.后续多期内容将以Minecraft(我的世界)模组教学为背景展开.

    *每期叠甲*:

    时间仓促,水平有限,文中难免存在缺点和错误,恳请广大开发者和从业者指正.

    首先,我们需要了解一下 *Java* 的基础语法.我将其分成四个部分:

    - 变量、数据类型、运算符

    - 控制流程(if/for/while)

    - 方法(函数)的定义和调用

    - 数组和集合(List/Map)

    首先先向各位介绍Java语言的变量.一共有八种```
    // 整数类型

    byte myByte = 127; // 8位,范围 -128 到 127

    short myShort = 32000; // 16位,范围 -32768 到 32767

    int myInt = 2147483647; // 32位,最常用的整数类型

    long myLong = 9223372036854775807L; // 64位,注意末尾的 L

    // 浮点类型

    float myFloat = 3.14f; // 32位,注意末尾的 f

    double myDouble = 3.14159265359; // 64位,默认的小数类型

    // 字符类型

    char myChar = 'A'; // 16位 Unicode 字符

    // 布尔类型

    boolean myBoolean = true; // 只有 true 或 false
    ``除了基本类型,其他都是引用类型(对象)``

    // 字符串(最常用的引用类型)

    String MyCodes = "mycodes";

    String fileName = "filename";

    // 数组

    int\[\] numbers = {1, 2, 3, 4, 5};

    String\[\] names = new String[10]; // 创建长度为 10 的数组

    // 对象

    File myFile = new File(new xxxxxx); // 这里的问题后面具体说
    ```以上就是 Java 中变量的分类:*八种基本类型* + 无数种*引用类型*.接下来我们逐部分展开.


    一、变量、数据类型、运算符

    1.1 变量的声明

    变量声明遵循"*类型 变量名*"的格式:```

    int age = 18; // 声明一个 int 变量并赋初值 18

    double height = 1.75; // 声明一个 double 变量

    String name; // 只声明,不赋值(此时是 null)

    name = "lihua"; // 之后再赋值
    ```1.2 变量的命名规则

    - 只能由 *字母、数字、下划线_、美元符号 $* 组成

    - *不能以数字开头*,不能是 Java 关键字(如 class、new、int)

    - 推荐使用*驼峰命名法*:myName、fileName、playerCount```

    int 2count; // 不能以数字开头

    int class; // class 是关键字

    int playerCount; // 驼峰命名,推荐
    ```1.3 运算符

    Java 的运算符分为四类,在开发中非常常用:

    第 1 列 |
    第 2 列 |
    第 3 列 |
    第 4 列 |

    类型 |
    运算符 |
    说明 |
    |

    算术 |
    + - * / % |
    % 是取余,如 7 % 3 = 1 |
    |

    赋值 |
    = += -= *= /= %= |
    x += 5 等价于 x = x + 5 |
    |

    比较 |
    == != > < >= <= |
    结果是 boolean |
    |

    逻辑 |
    && || ! |
    与、或、非 |
    |

    |
    |
    |
    |```

    int a = 10;

    int b = 3;

    // 这里的System.out.println() 类似于Python的print

    System.out.println(a + b); // 13

    System.out.println(a % b); // 1

    System.out.println(a > b); // true

    System.out.println(a == b); // false

    boolean isDay = true;

    boolean isRain = false;

    System.out.println(isDay && isRain); // false,两个都为 true 才为 true

    System.out.println(isDay || isRain); // true,有一个为 true 就为 true

    System.out.println(!isDay); // false,布尔值取反

    
    **二、控制流程(if/for/while)**
    
    **2.1 if 判断**```
    
    int hp = 50;
    
    if (hp <= 0) {
    
        System.out.println("玩家已死亡");
    
    } else if (hp <= 20) {
    
        System.out.println("血量未满");
    
    } else {
    
        System.out.println("血量已满");
    
    }
    ```**2.2 for 循环**```
    
    // 一共执行 10 次:当 i = 0,1,2,...,9 时各执行一次;i = 10 时条件不成立,循环结束
    
    for (int i = 0; i < 10; i++) {
    
        System.out.println("第 " + i + " 次循环");
    
    }
    ````for` 的三段分别是:初始化、循环条件、步进.`i++` 表示每次加一.
    
    **2.3 while 循环**```
    
    int count = 0;
    
    while (count < 5) {          // 先判断,后执行
    
        System.out.println("count = " + count);
    
        count++;
    
    }
    
    int a = 0;
    
    do {                          // 先执行一次,再判断
    
        System.out.println(a);
    
        a++;
    
    } while (a < 3);
    ```区别:`while` 可能一次都不执行,而 `do...while` ****至少执行一次****.
    
    **2.4 增强 for 循环(foreach)**
    
    遍历数组或集合时非常简洁,后面会频繁用到:```
    
    int[] scores = {60, 80, 100};
    
    for (int s : scores) {
    
        System.out.println(s);
    
    }
    ```> `for`/`while` 本身非常轻量,单层循环开销极小.真正要注意的是****嵌套循环****——循环套循环,每多一层,执行次数就成倍增长;嵌套多一层,压力就成倍增长.另外增强 `for` 只是语法糖,遍历数组时性能与下标循环几乎一样,不用担心它"更慢".(至于"到底有多快、差距有多大",有一种专门衡量的方法,后面会再讲)
    
    ---
    
    **三、方法(函数)的定义和调用**
    
    方法是把一段代码封装起来,方便重复调用.
    
    **3.1 基本结构**```
    
    修饰符 返回值类型 方法名(参数列表) {
    
        // 方法体
    
        return 返回值;
    
    }
    ``````
    
    // 无返回值的方法
    
    public static void greet(String name) {
    
        System.out.println("你好, " + name + "!");
    
    }
    
    // 有返回值的方法
    
    public static int add(int x, int y) {
    
        return x + y;
    
    }
    
    // 调用
    
    greet("mc");           // 你好, mc!
    
    int sum = add(3, 4);   // sum = 7
    ```- `void` 表示没有返回值
    
    - `return` 会结束方法并返回结果
    
    - 调用时传入的实参要与参数列表一一对应
    
    **3.2 方法重载(Overload)**
    
    同一个类中,方法名相同但****参数列表不同****,叫重载.调用时按传入的参数自动匹配:```
    
    public static int add(int a, int b) {
    
        return a + b;
    
    }
    
    public static int add(int a, int b, int c) {
    
        return a + b + c;
    
    }
    
    add(1, 2);       // 调用第一个,结果 3
    
    add(1, 2, 3);    // 调用第二个,结果 6

    四、数组和集合(List/Map)

    4.1 数组

    数组长度*固定*,创建后不可改变:```

    int[] nums = {1, 2, 3}; // 方式一:直接初始化

    String[] names = new String[5]; // 方式二:指定长度,默认 null

    System.out.println(nums[0]); // 1,下标从 0 开始

    nums[1] = 100; // 修改元素

    System.out.println(nums.length); // 3,数组长度
    ```> 数组是*连续内存*,几乎零额外开销,是占用最小的容器;缺点是长度固定,不能自动扩容.

    4.2 List(列表)

    比数组灵活,长度可以动态变化.最常用的是 ArrayList:```

    import java.util.ArrayList;

    import java.util.List;

    List<String> items = new ArrayList<>(); // 新建一个空的字符串列表

    // 我是我的世界mod开发者,这里很多地方就用mc的元素了

    items.add("sword"); // 添加元素

    items.add("pickaxe");

    items.remove("sword"); // 删除元素

    System.out.println(items.size()); // 1,当前元素个数

    System.out.println(items.get(0)); // pickaxe,按下标取值
    ```<> 里的类型叫*泛型*,表示这个列表里装的是什么类型.

    ArrayList 底层是会自动扩容的数组,每个元素存的只是*引用*(64 位 JVM 下约 8 字节),元素对象本身占的内存另算;扩容时会把旧数组整体拷贝一份(约扩到 1.5 倍).按下标取元素很快;但 contains(x) / remove(x) 要逐个比较,数据量大时别在循环里反复调用.

    4.3 Map(映射表)

    以"键-值对"存储数据,就像一本字典.最常用的是 HashMap:```

    import java.util.HashMap;

    import java.util.Map;

    Map<String, Integer> inventory = new HashMap<>();

    inventory.put("diamond", 5); // 存入键值对

    inventory.put("iron", 12);

    System.out.println(inventory.get("diamond")); // 5,按键取值

    inventory.put("diamond", 6); // 重复 put,会覆盖旧值

    System.out.println(inventory.containsKey("iron")); // true,是否包含某个键
    ``> HashMap 的 get/put 都很快,适合"按键取值".但它内存开销比 List 大不少:底层有一块桶数组,每个键值对还要额外包装成 Node` 对象,存的条目越多,差距越明显.


    朝花夕拾:回到之前 File 的问题

    开头我们写了这样一行:```

    File myFile = new File(new xxxxxx);
    ``这行代码****是有问题的****.new xxxxxx 是想再创建一个对象传给 File 的构造方法,但 File 的常用构造方法接收的是一个****路径字符串****,而不是另一个对象.正确写法如下:``

    // 方式一:直接传入文件路径(注意反斜杠要写两个)

    File myFile = new File("D:\\mc\\mod\\config.txt");

    // 方式二:父目录 + 文件名

    File parent = new File("D:\\mc\\mod");

    File myFile2 = new File(parent, "config.txt");
    ``> 小知识:File 并不代表"文件内容",它只是对文件或目录****路径****的抽象.真正读写文件内容是后面会讲到的 FileInputStream、FileWriter` 等.


    总结

    本期我们完成了 Java 入门第一课:

    - *八种基本类型*(byte/short/int/long/float/double/char/boolean)和*引用类型*(String、数组、对象)

    - *运算符*:算术、赋值、比较、逻辑

    - *控制流程*:if、for、while、增强 for

    - *方法*:定义、调用、重载

    - *数组与集合*:数组、List、Map

    掌握了以上基础,就可以开始阅读和编写简单的 Java 程序了.

    : )

    主楼
  • Mulin_Zz

    零基础,学 IT, 就来 Linuxdo​^-^狠狠赚它一笔

    #1
  • xianaldai

    其实我想赚点token,大半夜写稿子好饿啊

    #2
  • DIAVE971

    大半夜的,先到俺收藏夹里面吃灰吧 ^-^

    #3
  • dongka

    在这个vibe coding时代,做编程语言基础教程吗 ^-^

    #4
  • xianaldai

    我们当然会用ai生成大段的代码,但是看得懂看得透是你能写出好项目的第一步,始终指望ai,人类的编程能力会退化的,而且我不认为ai有能力发现自己写的代码存在的隐蔽的安全问题,ai总是信誓旦旦的拍它的滚木胸脯保证它的代码很棒了.

    如果写的水平全靠ai,永远只是自娱自乐而已.换一个人,用ai照样水平差不多

    #5

发表回复

登录后回复