Java 快速入门笔记:从基础语法到 Spring Boot 实战

Java 快速入门笔记:从基础语法到 Spring Boot 实战

本文面向有其他语言(如 Go、C++)编程经验的开发者,系统梳理了 Java 语言的核心知识点,包括 JDK/JRE 区别、Maven 项目管理、数据类型、集合框架、IO 模式、多线程编程、Spring Boot 快速入门和 JNI 调用等内容,帮助你快速建立 Java 知识体系。


一、Java 开发环境

1.1 JDK 与 JRE 的区别

JDK(Java Development Kit) 是 Java 开发工具包,包含了编译器(javac)、调试器、Java 运行时等工具。JRE(Java Runtime Environment) 是 Java 运行时环境,只包含运行 Java 程序所需的组件。

简单来说:JDK 包含 JRE。如果你只需要运行 Java 程序,安装 JRE 即可;如果要开发 Java 程序,需要安装 JDK。

复制代码
JDK 目录结构(JDK 8):
Java/
├── jdk1.8.0_351/        # JDK 安装目录
│   ├── bin/             # 开发工具(javac、java、jar 等)
│   ├── lib/             # 开发库
│   └── jre/             # 自带的 JRE
└── jre1.8.0_351/        # 独立的 JRE

API 文档参考:

1.2 Maven 项目管理

Maven 是 Java 的项目管理和构建工具(类似于 C++ 的 CMake、Go 的 Go Modules),负责依赖管理、编译、打包等。

安装与配置国内镜像源:

在 Maven 安装目录的 conf/settings.xml 中替换镜像配置:

xml 复制代码
<mirrors>
    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>

常用 Maven 命令:

bash 复制代码
# 清理 + 编译 + 打包(跳过测试)
mvn clean compile package -Dmaven.test.skip=true

# 清理已编译的目标文件
mvn clean

# 打包
mvn package

# 安装依赖到本地仓库
mvn install

pom.xml 是 Maven 项目的核心配置文件(类似于 CMake 的 CMakeLists.txt),定义了项目依赖、插件和构建配置。

Java 工程以 jar 包的形式运行,Maven 负责将源码编译并打包为可执行的 jar 文件。

1.3 IDE 选择

推荐使用 IntelliJ IDEA(官网有免安装的社区版),开箱即用。配置要点:

  • 设置 Maven 路径和 settings.xml 地址
  • 设置 JDK 路径

VSCode 开发 Java: 安装 Java Extension Pack 后,可以通过以下方式引入第三方 jar 包:

json 复制代码
// settings.json
{
    "java.project.referencedLibraries": [
        "lib/**/*.jar",
        "c:\\Users\\Mr.Zhou\\Downloads\\javax.mail-1.6.2.jar"
    ]
}

1.4 Java 文件与类的基本规则

  • 一个 Java 文件中只能存在一个 public
  • Java 文件命名必须是 public 类名.java
  • 类名建议大写开头,方法与成员变量建议小写开头

二、基础数据类型与访问修饰符

2.1 基本数据类型

Java 中没有有符号与无符号之分,全是有符号类型:

类型 存储大小 取值范围 备注
boolean 1 字节 true / false 布尔型
byte 1 字节 -128 ~ 127 字节(存储 ASCII 或二进制)
char 2 字节 0 ~ 65535 字符(如 char c = '你'
short 2 字节 -32768 ~ 32767 短整型
int 4 字节 -2^31 ~ 2^31-1 整型
long 8 字节 -2^63 ~ 2^63-1 长整型(常量加 L 后缀)
float 4 字节 --- 单精度浮点(常量加 F 后缀)
double 8 字节 --- 双精度浮点(默认)

包装类型(Wrapper Class): 每个基本类型都有对应的包装类(IntegerLongDouble 等),在集合框架中只能使用包装类型。

java 复制代码
// 字符串转数字
int d = Integer.valueOf("1234");

// 数字转字符串
String s = String.valueOf(1234);
// 或
String s = Integer.toString(1234);

2.2 四种访问修饰符

修饰符 同一个类 同一个包 子类 任何地方
public Y Y Y Y
protected Y Y Y
default(不写) Y Y
private Y

注意:

  • protectedprivate 不能修饰外部类
  • 不写修饰符则默认为 defaultdefault 关键字不需要写出来(写出来反而会报错)
  • synchronized 修饰符可以与四种访问修饰符组合使用,表示方法同一时间只能被一个线程访问

2.3 引用类型 vs 值类型

与 Go 语言有明显区别:Java 中除了 8 种基础数据类型(booleanbytecharshortintlongdoublefloat)以外,所有类类型都是引用类型。基础数据类型的数组类型也是引用类型。

java 复制代码
// Go 中数组传递是值拷贝
// Java 中数组传递是引用传递
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr1[0] = 99;
System.out.println(arr2[0]);  // 99(跟着变了)

三、String 与字符串操作

3.1 String 的不可变性

Java 的 String 与 Go 的 string 一样,定义后便无法修改。如需可修改的字符串,使用 StringBuffer(线程安全)或 StringBuilder(非线程安全,性能更好):

java 复制代码
// String 不可变
String s = "hello";
s = s + " world";  // 实际是创建了新的 String 对象

// StringBuilder 可变
StringBuilder sb = new StringBuilder("hello");
sb.append(" world");
String result = sb.toString();

3.2 字符串池

Java 中通过双引号创建的字符串会进入字符串常量池,相同内容的字符串共享同一引用:

java 复制代码
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");

System.out.println(s1 == s2);       // true(指向字符串池中同一对象)
System.out.println(s1 == s3);       // false(s3 在堆上创建新对象)
System.out.println(s1.equals(s3));  // true(值相等)

推荐使用 .equals() 比较字符串内容 ,而不是 ==

3.3 常用字符串操作

java 复制代码
// 格式化字符串(类似 C 的 sprintf)
String formatted = String.format("Name: %s, Age: %d", "Tom", 25);

// 大小写转换(Go 中需要 strings 包,Java String 自带)
String upper = "hello".toUpperCase();
String lower = "WORLD".toLowerCase();

// 字符串与字节数组互转
byte[] bytes = "hello".getBytes();
String fromBytes = new String(bytes);

// String.valueOf() 万能转换
String s1 = String.valueOf(123);     // 数字转字符串
String s2 = String.valueOf(true);    // 布尔转字符串
String s3 = String.valueOf(3.14);    // 浮点转字符串

注意: 所有类型的 toString() 方法并不是都返回有意义的字符串内容。大部分对象直接调用 toString() 输出的是地址信息,转之前需要确认该类是否重写了 toString()


四、时间操作

java 复制代码
import java.text.SimpleDateFormat;
import java.util.Date;

// 获取时间戳(两种方式)
long ts1 = System.currentTimeMillis();
long ts2 = new Date().getTime();

// Date 格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String formatted = sdf.format(new Date());

// printf 格式化时间(方便)
System.out.printf("%tF %tT", new Date(), new Date());
// 等价于 yyyy-MM-dd HH:mm:ss

五、集合框架

Java 集合框架是处理数据集合的核心工具,对应 Go 中的 slice 和 map,但功能更加丰富。

5.1 List(列表)

List 是有序可重复的集合,对应 Go 的 slice:

java 复制代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 创建 ArrayList
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");

// 访问元素
String first = list.get(0);  // apple

// 遍历
for (String item : list) {
    System.out.println(item);
}

// 数组转 List
String[] arr = {"a", "b", "c"};
List<String> listFromArray = Arrays.asList(arr);

// 数组截取(类似 Go 的 slice[start:end])
String[] original = {"a", "b", "c", "d", "e"};
String[] sub = Arrays.copyOfRange(original, 1, 4);  // {"b", "c", "d"}

注意: ArrayList 的泛型参数只支持包装类型,不支持基本类型(如 int 要用 Integer)。

5.2 Map(映射)

Map 是键值对集合,对应 Go 的 map:

java 复制代码
import java.util.HashMap;
import java.util.Map;

// 创建 HashMap
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 87);
scores.put("Charlie", 92);

// 访问
int score = scores.get("Alice");  // 95

// 判断 key 是否存在
if (scores.containsKey("Alice")) {
    System.out.println("Found Alice");
}

// 遍历
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

5.3 Set(集合)

Set 是无序不重复的集合:

java 复制代码
import java.util.HashSet;
import java.util.Set;

Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("apple");  // 重复元素不会添加

System.out.println(set.size());  // 2

5.4 迭代器

java 复制代码
import java.util.Iterator;
import java.util.List;

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");

// 使用迭代器遍历(可以在遍历时安全删除元素)
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String item = it.next();
    if (item.equals("b")) {
        it.remove();  // 安全删除
    }
}

六、接口与抽象类

6.1 抽象类

java 复制代码
abstract class Animal {
    // 抽象方法(只有声明,没有实现)
    abstract void makeSound();

    // 普通方法
    void sleep() {
        System.out.println("sleeping...");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof!");
    }
}

抽象类总结:

  1. 抽象类不能被实例化
  2. 抽象类中不一定包含抽象方法,但有抽象方法的类必定是抽象类
  3. 构造方法和 static 方法不能声明为抽象方法
  4. 子类必须实现所有抽象方法,否则子类也必须声明为抽象类

6.2 接口(Interface)

Java 的接口和 Go 的接口概念非常相似,只不过 Go 是鸭子模式(隐式实现),Java 需要使用 implements 关键字(显式实现):

java 复制代码
interface Writer {
    int write(byte[] b);
}

// 实现接口
class FileWriter implements Writer {
    @Override
    public int write(byte[] b) {
        // 实现写入逻辑
        return b.length;
    }
}

// 使用接口作为参数
private static int testInterface(Writer w, byte[] data) {
    return w.write(data);
}

接口特点:

  • 接口不能用于实例化对象
  • 接口没有构造方法
  • 接口中所有方法默认是抽象的(Java 8 后可用 default 修饰非抽象方法)
  • 接口不能包含成员变量(除 staticfinal 变量)
  • 接口支持多继承

七、IO 模式(BIO / NIO / AIO)

7.1 三种 IO 模式对比

模式 全称 特点
BIO Block IO(阻塞 IO) 最简单,一个连接需要一个线程处理
NIO Not-Block IO(非阻塞 IO) 类似 Linux 的 select/epoll 多路复用,一个线程处理大量连接
AIO Asynchronous IO(异步 IO) 异步非阻塞,操作系统完成后再回调通知

7.2 ByteBuffer(NIO 核心)

java.nio.ByteBuffer 是 NIO 中的核心缓冲区类,类似于 Go 的 bytes.Buffer

java 复制代码
import java.nio.ByteBuffer;
import java.util.Arrays;

// 分配内存
ByteBuffer buffer = ByteBuffer.allocate(1024);

// 写入数据
buffer.put("hello world".getBytes());

// 读取数据
byte[] allData = buffer.array();

// 获取实际写入的数据长度
int length = buffer.position();

// 获取有效数据
byte[] validData = Arrays.copyOfRange(allData, 0, length);

注意: ByteBuffer 需要预先指定容量,追加数据超出容量会抛异常。如果需要自动管理容量,可以使用 StringBuilder 代替。


八、多线程编程

Java 内置多线程支持,创建线程比很多语言更简单。

8.1 三种创建线程的方式

方式一:实现 Runnable 接口

java 复制代码
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}

public class Main {
    public static void main(String[] args) {
        Thread th = new Thread(new MyRunnable(), "my-thread");
        th.start();  // start() 内部调用 run()
    }
}

方式二:继承 Thread 类

java 复制代码
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread running: " + getName());
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread th = new MyThread();
        th.start();
    }
}

方式三:实现 Callable 接口(有返回值)

java 复制代码
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        FutureTask<Integer> task = new FutureTask<>(new MyCallable());
        Thread th = new Thread(task);
        th.start();

        // 获取返回值(类似 C++ 的 future/promise)
        Integer result = task.get();
        System.out.println("Sum: " + result);  // 5050
    }
}

本质上,以上三种方式都是围绕 Thread 类的 run 方法。 start() 方法会启动新线程并调用 run(),直接调用 run() 只是在当前线程执行。

8.2 synchronized 同步

java 复制代码
class Counter {
    private int count = 0;

    // 同步方法:同一时间只能被一个线程访问
    public synchronized void increment() {
        count++;
    }

    // 同步代码块
    public void decrement() {
        synchronized (this) {
            count--;
        }
    }

    public int getCount() {
        return count;
    }
}

九、Spring Boot 快速入门

Spring Boot 是 Java 生态中最流行的 Web 开发框架,极大简化了 Spring 应用的配置和部署。

9.1 引入第三方库

Java 引入第三方库的方式:

  1. Maven/Gradle 依赖管理:pom.xml 中添加依赖(推荐)
  2. 手动引入 jar 包: 将 jar 放入 classpath%JAVA_HOME%\jre\lib\ext 目录
  3. VSCode 引用:settings.jsonjava.project.referencedLibraries 中配置
xml 复制代码
<!-- pom.xml 中添加 Spring Boot 依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

9.2 项目分层结构

Java Web 项目通常采用 MVC 分层架构:

复制代码
src/main/java/com/example/
├── controller/     # 控制层:处理 HTTP 请求
├── service/        # 业务层:处理业务逻辑
├── dao/            # 数据访问层:数据库操作
├── model/
│   ├── entity/     # 实体类:与数据库表对应
│   ├── vo/         # 视图对象:与前端页面对应
│   └── dto/        # 数据传输对象:entity 与 vo 之间的转换
└── Application.java  # 启动类

9.3 简单的 REST API 示例

java 复制代码
// 启动类
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 控制器
@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello, %s!", name);
    }

    @PostMapping("/user")
    public User createUser(@RequestBody User user) {
        // 处理逻辑
        return userService.save(user);
    }
}

9.4 MyBatis 条件查询

在 DAO 层的 XML 映射文件中,可以直接在 SQL 中使用条件判断:

xml 复制代码
<select id="queryRecords" resultType="PatrolRecord">
    SELECT id, patrol_line_plan_id, name, company_code
    FROM patrol_line_record
    WHERE delete_flag = 0
    AND company_code REGEXP CONCAT('^(',
        CONCAT_WS('|',
        <foreach collection="orgCodes" item="code" separator=",">
            #{code}
        </foreach>
        ), ')')
    <if test="name != null and name != ''">
        AND name LIKE CONCAT('%', #{name}, '%')
    </if>
    <if test="startDate != null and endDate != null">
        AND line_date BETWEEN #{startDate} AND #{endDate}
    </if>
    <if test="statusId != null">
        AND status_id = #{statusId}
    </if>
    ORDER BY create_time DESC
</select>

这种方式的优点是将条件逻辑写在 SQL 中,避免在业务层做过多的 if 判断。


十、JNI(Java Native Interface)调用

JNI 允许 Java 代码调用本地(Native)方法,即 C/C++ 编写的动态链接库。

10.1 基本流程

  1. 在 Java 类中声明 native 方法
  2. 使用 javac 编译 Java 文件
  3. 使用 javah 生成 C/C++ 头文件
  4. 用 C/C++ 实现本地方法
  5. 编译为动态链接库(.dll.so
  6. 在 Java 中加载库并调用
java 复制代码
public class NativeDemo {
    // 加载本地库
    static {
        System.loadLibrary("mynative");
    }

    // 声明本地方法
    public native String sayHello(String name);

    public static void main(String[] args) {
        NativeDemo demo = new NativeDemo();
        String result = demo.sayHello("World");
        System.out.println(result);
    }
}

十一、常用工具与框架

11.1 JavaDoc 文档生成

类似 Go 的 godoc,Java 提供了 javadoc 工具,可以按照标准文档注释自动生成 HTML 文档:

java 复制代码
/**
 * 计算两个整数的和
 * @param a 第一个加数
 * @param b 第二个加数
 * @return 两数之和
 */
public int add(int a, int b) {
    return a + b;
}
bash 复制代码
# 生成文档
javadoc -d doc src/*.java

11.2 定时任务框架

xxl-job 是 Java 中常用的分布式任务调度框架,用于管理和执行定时任务,提供 Web UI 管理界面,支持任务执行记录查看。

11.3 Java 与 Go 常用操作对比

操作 Java Go
字符串转数字 Integer.valueOf("123") strconv.Atoi("123")
数字转字符串 String.valueOf(123) strconv.Itoa(123)
字符串大小写 s.toUpperCase() strings.ToUpper(s)
字节数组互转 "hello".getBytes() []byte("hello")
数组截取 Arrays.copyOfRange(arr, s, e) arr[s:e]
可变字符串 StringBuilder bytes.Buffer
动态数组 ArrayList<T> slice
哈希表 HashMap<K,V> map[K]V
格式化字符串 String.format() fmt.Sprintf()

总结

Java 作为一门成熟的企业级编程语言,拥有极其丰富的生态和完善的工具链。本文涵盖了以下核心知识点:

  1. 开发环境: JDK/JRE 区别、Maven 项目管理、IDE 配置
  2. 基础语法: 8 种基本数据类型、4 种访问修饰符、引用类型与值类型的区别
  3. 字符串操作: String 不可变性、字符串常量池、StringBuilder
  4. 集合框架: ArrayList(动态数组)、HashMap(哈希表)、Set(集合)、迭代器
  5. IO 模式: BIO(阻塞)、NIO(非阻塞多路复用)、AIO(异步非阻塞)
  6. 多线程编程: 三种创建线程方式、synchronized 同步机制
  7. Spring Boot: 快速构建 REST API、项目分层结构、MyBatis 条件查询
  8. JNI 调用: Java 调用 C/C++ 本地方法
  9. 常用工具: JavaDoc 文档生成、xxl-job 定时任务

Java 的强类型系统、成熟的集合框架和强大的生态使其成为企业级应用开发的首选语言。对于有 Go/C++ 背景的开发者,Java 的面向对象特性和丰富的标准库会带来不同的编程体验。


原始笔记来源:

  • zyh/LearnJava.java
相关推荐
极创信息2 小时前
信创产品认证怎么做?信创产品测试认证的主要流程
java·大数据·数据库·金融·软件工程
SamDeepThinking2 小时前
并发量就算只有2,该上锁还得上呀
java·后端·架构
Sam_Deep_Thinking2 小时前
如何让订单系统和营销系统解耦
java·架构·系统架构
lzhdim3 小时前
SQL 入门 12:SQL 视图:创建、修改与可更新视图
java·大数据·服务器·数据库·sql
FQNmxDG4S3 小时前
Maven依赖管理:版本冲突解决与生命周期控制
java·数据库·maven
傻瓜搬砖人4 小时前
Spring集成Web环境
java·spring·maven
FQNmxDG4S4 小时前
Java泛型编程:类型擦除与泛型方法的应用场景
java·开发语言·python
GottdesKrieges4 小时前
OceanBase恢复常见问题
java·数据库·oceanbase
IGAn CTOU4 小时前
Java高级开发进阶教程之系列
java·开发语言