Java 基础

概述

Java 用途

Java 是用于开发应用程序的编程语言程序就是计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合主要用于以下几个核心领域


Android 应用开发Java 是 Android 平台开发的主要语言之一许多我们日常使用的手机 App如 SpotifySignal 等都是使用 Java 构建的
企业级后端开发这是 Java 最重要的应用场景凭借其稳定性安全性和高并发处理能力Java 成为企业级服务端开发的首选大量的银行金融交易系统大型电商网站如 TwitterLinkedIn的后台都> 是由 Java 驱动的
大数据处理Java 是许多大数据技术生态的核心语言例如 Hadoop 和 Spark 等框架都是用 Java 编写的广泛用于处理和分析海量数据
桌面应用程序Java 可以开发跨平台的桌面软件著名的集成开发环境IDE如 IntelliJ IDEA 和 Eclipse 本身就是用 Java 开发的桌面应用
游戏开发Java 也被用于游戏开发最著名的例子就是风靡全球的沙盒游戏我的世界Minecraft
嵌入式系统与物联网 (IoT)得益于其跨平台和稳定性Java 还被应用于智能电视车载系统工业控制设备等嵌入式和物联网领域

Java 历史

🌱 起源OakJava (1991-1994)

Java 的故事始于 1991 年当时 Sun Microsystems 公司启动了一个名为绿色计划Green Project的秘密项目

  • 最初目标 由詹姆斯·高斯林James Gosling等人领导的团队旨在为下一代智能消费电子产品如机顶盒交互式电视开发一种新的编程语言
  • 命名Oak Gosling 将这门新语言命名为Oak橡树灵感来自他办公室窗外的一棵树然而由于硬件厂商接受度低该项目在消费电子市场遭遇失败
  • 关键转折 1994 年互联网Web开始兴起团队敏锐地意识到Oak 语言所具备的安全性网络移动性和跨平台特性完美契合了互联网网络即计算机的愿景
  • 正式更名 由于Oak已被注册为商标团队选择了Java作为新名字灵感来自印度尼西亚的爪哇咖啡

🚀 爆发互联网时代的宠儿 (1995-1999)

1995 年是 Java 历史上最重要的一年

  • 正式发布 1995 年 5 月 23 日Sun Microsystems 在 SunWorld 大会上正式发布 Java 1.0并提出了著名的口号 Write Once, Run Anywhere (WORA)一次编写到处运行
  • 引爆互联网 Java 的跨平台特性解决了当时软件开发的最大痛点Netscape Navigator 浏览器迅速集成 Java 技术使得 Java Applet小程序成为当时网页上实现动态交互的最热门技术

随后的几年是 Java 标准化和壮大的关键期

  • 1996年 JDK 1.0 正式发布标志着 Java 进入主流开发视野
  • 1997年 JDK 1.1 引入了 JDBC数据库连接RMI远程方法调用和内部类等特性完善了语言基础设施
  • 1998年 JDK 1.2 是一个里程碑版本它被重命名为 Java 2并首次将 Java 平台划分为三个版本这一战略奠定了 Java 随后二十年的发展格局
  • J2SE (Java 2 Standard Edition) 面向桌面和工作站的通用开发
  • J2EE (Java 2 Enterprise Edition) 面向服务器端企业级应用包含 EJBServletJSP 等规范
  • J2ME (Java 2 Micro Edition) 面向移动设备如功能手机和嵌入式系统

🏛️ 统治企业级开发的霸主 (2000-2009)

进入 21 世纪随着企业信息化的深入Java 迅速确立了在企业后端开发的统治地位

  • 企业首选 尽管早期的 EJB 因配置繁琐而备受诟病但 Java 凭借其稳定性安全性和庞大的类库成为了银行电信和电商等核心系统的首选语言
  • 语法革命 (Java 5) 2004 年发布的 JDK 5.0 是一次巨大的升级引入了泛型注解枚举自动装箱等特性极大地提升了代码的简洁性和类型安全
  • 开源化 (Java 6) 2006 年Sun 公司宣布将 Java 技术作为免费软件对外发布此举极大地推动了 Java 社区的繁荣
  • 巨头更迭 (2009) 甲骨文公司Oracle宣布收购 Sun 公司Java 的归属权随之转入 Oracle 麾下

🏎️ 进化云原生时代的重生 (2010-至今)

在 Oracle 的推动下Java 进入了一个快速有序的现代化演进阶段

  • 里程碑式的 Java 8 2014 年发布的 Java 8 至今仍是影响最深远的版本之一它引入的 Lambda 表达式和 Stream API 让 Java 拥有了函数式编程能力彻底改变了开发者的编码方式15
  • 模块化与新节奏 (Java 9) 2017 年发布的 Java 9 引入了模块化系统Project Jigsaw并开启了每6个月发布一个新版本每2年发布一个长期支持版本LTS的新节奏25
  • 拥抱云原生 (Java 21) 2023 年发布的 JDK 21 标志着 Java 迈入了协程时代核心特性虚拟线程Virtual Threads让开发者能够轻松创建百万级线程极大地提升了高并发场景下的性能为云原生应用开发注入了强大动力5

Java 特点

⭐⭐ 核心优势


跨平台性 (Write Once, Run Anywhere)
这是 Java 最显著的特征Java 代码在编译后不会生成特定操作系统的机器码而是生成一种中间代码——字节码这些字节码可以在任何安装了 Java 虚拟机 的硬件设备上运行JVM 负责将字节码解释或编译成对应平台的机器码从而实现了一次编写到处运行的愿景极大地提升了软件的可移植性


面向对象 (OOP)
Java 是一门纯粹的面向对象编程语言它完全基于对象的概念来组织代码并支持封装继承多态等核心特性这种编程范式使得代码更易于理解复用和维护特别适合开发大型复杂系统


简单易学
Java 的语法设计去除了 C++ 中复杂且容易出错的特性例如指针多重继承goto 语句同时它采用了自动垃圾回收机制来管理内存减轻了程序员的负担这使得 Java 语言相对简洁对于初学者来说非常友好


⭐⭐ 稳健与安全


健壮性 Java 通过多种机制来保证程序的稳定运行

  • 强类型检查 在编译和运行时都会进行严格的类型检查提前暴露错误
  • 异常处理 提供了完善的 try-catch-finally 机制来捕获和处理运行时错误防止程序意外崩溃
  • 自动内存管理 通过垃圾回收器自动回收不再使用的对象有效避免了内存泄漏和悬空指针等问题

安全性 Java 被设计用于网络和分布式环境其安全性是内置的

  • 沙箱机制 JVM 为代码提供了一个受限的运行环境限制其对本地系统资源如文件网络的访问权限防止恶意代码破坏系统
  • 字节码验证 在加载类文件时会进行严格的校验确保代码不会执行非法操作

⭐⭐ 高性能与并发


高性能
虽然早期 Java 因解释执行而性能受限但现代 JVM 引入了 即时编译 技术JIT 会将频繁执行的热点代码编译成本地机器码使其运行性能接近 C/C++ 等编译型语言


多线程支持
Java 在语言层面原生支持多线程编程开发者可以方便地创建和管理多个线程以实现并发执行任务这对于开发高并发的服务器端应用和响应迅速的图形界面程序至关重要


⭐⭐ 生态与扩展


分布式
Java 从诞生之初就具备网络基因内置了丰富的网络库java.netjava.rmi使得开发分布式应用如 Web 服务远程调用变得非常简单


动态性
Java 能够在运行时动态地加载类获取类信息并调用方法这一特性主要通过反射机制实现它是许多框架如 Spring实现依赖注入面向切面编程等功能的基础极大地增强了程序的灵活性


Java 运行机制

Java 的运行机制是其能够实现一次编写到处运行WORA的核心它并非直接由操作系统执行而是依赖于一个名为 Java 虚拟机 的中间层

简单来说Java 的运行机制可以分为三个核心阶段编译加载执行

⭐⭐ 核心组件JDKJRE 与 JVM

JDK (Java Development Kit) 是 Java 的开发工具包包含了编译器 (javac)调试器等开发工具开发者使用 JDK 将源代码编译成字节码
JRE (Java Runtime Environment) 是 Java 的运行时环境包含了 JVM 和核心类库普通用户只需安装 JRE 即可运行 Java 程序
JVM (Java Virtual Machine) 是 Java 虚拟机是整个运行机制的核心它是一个虚拟的计算机负责加载字节码并将其转换为特定平台的机器码来执行

⭐⭐ 阶段一编译从源码到字节码

这是 Java 程序运行的第一步发生在开发阶段

  1. 输入 开发者编写的 .java 源代码文件
  2. 工具 使用 JDK 中的 javac 编译器
  3. 过程 javac 编译器对源代码进行语法分析语义分析和字节码生成
  4. 输出 生成与平台无关的 .class 字节码文件此时的字节码并不是任何特定硬件的机器码而是一种 JVM 能够理解的中间指令集

⭐⭐ 阶段二加载类加载器的职责

当你在命令行执行 java HelloWorldJVM 启动并进入类加载阶段

  1. 加载 类加载器负责从文件系统或网络中找到 HelloWorld.class 文件并将其二进制字节流读入内存
  2. 链接
    • 验证 确保字节码是合法且安全的符合 JVM 规范防止恶意代码破坏系统
    • 准备 为类的静态变量分配内存并设置其初始默认值0null
    • 解析 将常量池内的符号引用如类名方法名替换为直接引用内存地址
  3. 初始化 执行类构造器 <clinit>() 方法为类的静态变量赋予代码中指定的初始值并执行静态代码块

⭐⭐ 阶段三执行执行引擎的魔法

类加载完成后JVM 的执行引擎开始接管执行 main 方法中的字节码现代 JVM 采用了一种混合模式来平衡启动速度和运行效率


混合执行模式

  1. 解释执行 (Interpreter)
    • 方式 像同声传译一样逐条读取字节码将其翻译成当前平台的机器码并执行
    • 优点 启动速度快无需等待编译
    • 缺点 运行效率较低因为同一段代码每次执行都需要翻译
  2. 即时编译 (JIT - Just-In-Time Compiler)
    • 方式 JVM 会监控程序运行当发现某个方法或代码块被频繁调用称为热点代码JIT 编译器会将其整个编译成本地机器码并缓存起来
    • 优点 后续调用该热点代码时直接执行高效的机器码运行速度极快接近 C/C++
    • 缺点 编译过程会消耗 CPU 和内存资源且首次执行时有延迟

总结 Java 程序启动时解释器优先执行保证快速响应在运行过程中JIT 编译器不断优化热点代码提升系统吞吐量这种解释器与编译器并存的策略是 Java 性能卓越的关键


⭐⭐ 内存管理自动垃圾回收

在整个执行过程中JVM 的运行时数据区负责管理内存其中最核心的机制之一是垃圾回收JVM 会自动追踪对象的引用情况当发现某些对象不再被任何引用指向时垃圾回收器会自动回收其占用的内存极大地减轻了开发者手动管理内存的负担和出错风险

安装运行

安装配置

JAVA 8 安装详解https://blog.csdn.net/suzengxin/article/details/115401549

运行程序

⭐⭐ 第一步开发程序

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

⭐⭐ 第二步编译程序

1
javac Hello.java

⭐⭐ 第三步运行程序

1
java Hello

转义字符

转义字符 描述
\t 制表符
\n 换行符
\r 回车
\" 双引号
\' 单引号
\\ 反斜杠

代码注释

单行注释

1
// 单行注释

多行注释

1
2
3
/*
多行注释
*/

文档注释

1
2
3
4
/**
* @author szxck
* @version 1.0
*/

⭐⭐ 生成 Java 文档

1
javadoc -d D:\\javadoc -author -version Hello.java

⭐⭐ 标准标签

标签名 用途说明 适用对象
@author 指明类或接口的作者 接口
@version 指定类或接口的版本信息 接口
@param 描述方法或构造函数的参数名称和含义 方法构造函数
@return 描述方法的返回值 方法
@throws 描述方法可能抛出的异常 方法构造函数
@exception @throws 功能相同用于描述异常 方法构造函数
@see 提供指向其他类方法或外部资源的参见链接 全局(类方法包等)
@since 指明该特性从哪个版本或日期开始引入 全局
@deprecated 标记该 API 已过时不建议使用 全局
@serial 用于序列化字段的文档说明 字段 (Field)
@serialData 描述通过 `writeObject` 或 `writeExternal` 写入的数据 方法 (通常为 writeObject)
@serialField 描述 `ObjectStreamField` 组件 字段

⭐⭐ 内联标签

这些标签用 {} 包裹可以嵌入到注释的任意文本中用于内联显示特殊内容或链接

标签名 用途说明
{@link} 内联插入一个指向其他类或成员的链接类似于 @see 但可嵌入文本
{@linkplain} {@link} 类似但链接文本以纯文本非代码样式显示
{@value} 显示静态字段常量的值
{@code} 将文本显示为代码样式通常用于表示关键字或代码片段并避免被解析为 HTML
{@literal} 显示文本而不进行任何转义显示原样文本不解析为 HTML 或其他标签
{@inheritDoc} 从直接父类或实现的接口中继承文档注释
{@docRoot} 指明生成的文档根目录的路径用于构建相对路径链接

⭐⭐ 不常用标签

标签名 用途说明
@category (非标准某些 Doclet 可能支持) 用于分类
@index (Java 8+) 强制将标识符添加到索引中
@apiNote (Java 8+) 提供关于 API 使用的额外说明非规范性
@implSpec (Java 8+) 提供实现者需要遵守的规范说明
@implNote (Java 8+) 提供关于实现的非规范性说明

数据类型

在 Java 中数据类型变量常量是编程的三大基石它们共同决定了程序如何存储和处理数据简单来说数据类型是容器的规格变量是可变的容器而常量是不可变的容器


数据类型用于定义变量或常量可以存储的数据种类以及占用内存的大小Java 是强类型语言每一个变量都必须先声明类型才能使用
变量变量是程序运行过程中值可以发生改变的数据存储单元你可以把它想象成一个贴了标签的盒子盒子的大小由数据类型决定里面的内容可以根据需要更换
常量常量是程序运行过程中值不能发生改变的数据 使用 final 关键字修饰的变量一旦赋值就不能再修改

类型描述

类型 关键字 字节/位数 取值范围 默认值 描述
整数型 byte 1字节 / 8位 -128 到 127 0 最小的整数类型常用于节省内存的场景如处理二进制数据
short 2字节 / 16位 -32768 到 32767 0 较少使用通常用于特定的内存优化场景
int 4字节 / 32位 -2³¹ 到 2³¹-1 0 最常用的整数类型也是整数字面量的默认类型
long 8字节 / 64位 -2⁶³ 到 2⁶³-1 0L 用于存储非常大的数值如时间戳文件大小定义时需在数值后加 L
浮点型 float 4字节 / 32位 约 ±3.4028235E+38 0.0F 单精度浮点数定义时需在数值后加 F
double 8字节 / 64位 约 ±1.7976931348623157E+308 0.0D 双精度浮点数精度更高是浮点数字面量的默认类型
字符型 char 2字节 (16位) 0 到 65535 (\u0000 到 \uffff) \u0000 使用单引号 '' 表示例如'中''国''A'
布尔型 boolean 1 位 | 1 字节 true (真) 或 false (假) false 常用于条件判断和循环控制

类型转换

⭐⭐ 自动类型转换隐式转换

这是 Java 编译器自动完成的转换也叫拓宽转换Widening Conversion当你把一个小杯子里的水倒进一个大杯子不会溢出因此是安全的

转换规则 容量小的数据类型可以直接赋值给容量大的数据类型

byte → short → int → long → float → double

char → int → long → float → double

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1. 赋值时的自动转换
int a = 100;
long b = a; // int -> long自动转换
double c = a; // int -> double自动转换

// 2. char的特殊性
char ch = 'A'; // 'A'的Unicode值是65
int ascii = ch; // char -> int自动转换结果为65

// 3. 运算时的自动提升
byte x = 10;
short y = 20;
// byte + short -> 计算前先全部转为 int所以结果必须用 int 或更大的类型接收
int result = x + y;

float f = 1.5f;
double d = 2.5;
// float + double -> 提升为 double
double sum = f + d;

⭐⭐ 强制类型转换显式转换

这是程序员明确指示编译器进行的转换也叫窄化转换Narrowing Conversion当你把一个大杯子里的水倒进一个小杯子可能会溢出或洒掉数据丢失因此需要你手动负责

精度丢失 浮点数转整数时直接截断小数部分不是四舍五入

数据溢出 数值超过了目标类型的取值范围会发生截断溢出

1
2
3
4
5
6

double pi = 3.1415926;
int intPi = (int) pi; // 强制转换结果为 3直接舍弃小数

long bigNum = 3000000000L;
int num = (int) bigNum; // 强制转换由于long范围大于int可能导致溢出结果可能为负数

二进制

计算机中的数据存储 学习笔记

各个进制之间相互转换 学习笔记

原码反码和补码 学习笔记

运算符

Java运算符是用于对变量和值进行操作的符号

算术运算符

算术运算符用于执行基本的数学运算

运算符 名称 示例 描述
+ 加法 a + b 相加两个操作数
- 减法 a - b 从第一个操作数中减去第二个操作数
* 乘法 a * b 相乘两个操作数
/ 除法 a / b 分子除以分母
% 取模 ++a a++ 返回除法的余数
++ 自增 ++a a++ 操作数的值增加1
-- 自减 --a a-- 操作数的值减少1

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ArithmeticOperators {
public static void main(String[] args) {
int a = 10, b = 3;
System.out.println("a + b = " + (a + b)); // 13
System.out.println("a - b = " + (a - b)); // 7
System.out.println("a * b = " + (a * b)); // 30
System.out.println("a / b = " + (a / b)); // 3 (整数除法)
System.out.println("a % b = " + (a % b)); // 1

int c = 5;
System.out.println("c++ = " + (c++)); // 5 (先使用后自增)
System.out.println("++c = " + (++c)); // 7 (先自增后使用)
}
}

关系运算符

关系运算符用于比较两个值返回布尔值true或false

运算符 名称 示例 描述
== 等于 a == b 检查两个操作数的值是否相等
!= 不等于 a != b 检查两个操作数的值是否不相等
> 大于 a > b 检查左操作数的值是否大于右操作数的值
< 小于 a < b 检查左操作数的值是否小于右操作数的值
>= 大于等于 a >= b 检查左操作数的值是否大于或等于右操作数的值
<= 小于等于 a <= b 检查左操作数的值是否小于或等于右操作数的值

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
public class RelationalOperators {
public static void main(String[] args) {
int a = 10, b = 20;
System.out.println("a == b: " + (a == b)); // false
System.out.println("a != b: " + (a != b)); // true
System.out.println("a > b: " + (a > b)); // false
System.out.println("a < b: " + (a < b)); // true
System.out.println("a >= b: " + (a >= b)); // false
System.out.println("a <= b: " + (a <= b)); // true
}
}

逻辑运算符

逻辑运算符用于组合多个布尔表达式

运算符 名称 示例 描述
&& 短路与 a && b 如果两个操作数都为真则返回结果为真
|| 短路或 a || b 如果两个操作数有一个为真则返回结果为真
& 逻辑与 a & b 如果两个操作数都为真则返回结果为真
| 逻辑或 a | b 如果两个操作数有一个为真则返回结果为真
^ 逻辑异或 a ^ b 两个操作数一个为真一个为假则返回结果为真
! 取反 !a 如果操作数为真则返回结果为假反转逻辑状态

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// &&如果第一个条件为false不会检查第二个条件
// & 如果第一个条件为false还会继续检查第二个条件
// ||如果第一个条件为true不会检查第二个条件
// | 如果第一个条件为true还会继续检查第二个条件
public class LogicalOperators {
public static void main(String[] args) {
boolean x = true, y = false;

System.out.println("x && y: " + (x && y)); // false
System.out.println("x || y: " + (x || y)); // true
System.out.println("!x: " + (!x)); // false

// 短路示例
int a = 5, b = 10;
if (a > 10 && b++ > 5) {
System.out.println("条件成立");
}
System.out.println("b = " + b); // b仍然是10因为短路
}
}

位运算符

位运算符对整数类型的位进行操作

运算符 名称 示例 描述
& 按位与 a & b 只有当两个对应的二进制位都为 1 时结果的该位才为 1否则为 0
| 按位或 a | b 只要有一个对应的二进制位为 1结果位就为 1否则为 0
^ 按位异或 a ^ b 当两个对应的二进制位不相同时结果位为 1否则相同时为 0
~ 按位取反 ~a 当原二进制位为 0 时结果位为 1当原位为 1 时结果位为 0
<< 左移 a << 1 将a的二进制位向左移动1位右边空出的位补入 0
左移几位相当于乘以 2 的几次方
>> 右移 a >> 1 将a的二进制位向右移动1位左边空出的位补入符号位
右移几位相当于除以 2 的几次方
>>> 无符号右移 a >>> 1 将a的二进制位向右移动1位左边空出的位补入 0
处理的是二进制位的移动而不是数学计算

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 在 Java 中所有整数在计算机底层都以 二进制补码 的形式存储
// 对于正数来说其原码反码和补码是相同的
// 对于负数来说原码反码和补码计算遵循一套固定的规则
// 反码 = 原码的符号位不变其他位按位取反
// 补码 = 反码 + 1
public class BitwiseOperators {
public static void main(String[] args) {
int a = 6; // 二进制: 0000 0000 0000 0000 0000 0000 0000 0110
int b = 3; // 二进制: 0000 0000 0000 0000 0000 0000 0000 0011
System.out.println("a & b = " + (a & b)); // 2 (0010)
System.out.println("a | b = " + (a | b)); // 7 (0111)
System.out.println("a ^ b = " + (a ^ b)); // 5 (0101)
// a = 6 因为是正数所以 6 补码跟原码一致
// 补码 0000 0000 0000 0000 0000 0000 0000 0110
// 取反 1111 1111 1111 1111 1111 1111 1111 1001 (按位取反符号位是1所以是负数)
// 转反码 1111 1111 1111 1111 1111 1111 1111 1000 (负数反码 = 补码 - 1)
// 转原码 1000 0000 0000 0000 0000 0000 0000 0111 (符号位不变数值位取反)
System.out.println("~a = " + (~a)); // -7 (转十进制)
System.out.println("a << 1 = " + (a << 1)); // 12 (1100) > 6 * 2的1次方
System.out.println("a >> 1 = " + (a >> 1)); // 3 (0011) > 6 / 2的1次方
}
}

赋值运算符

赋值运算符用于给变量赋值

运算符 示例 等价于
= a = 5 简单赋值
+= a += 5 a = a + 5
-= a -= 5 a = a - 5
*= a *= 5 a = a * 5
/= a /= 5 a = a / 5
%= a %= 5 a = a % 5
&= a &= 5 a = a & 5
|= a |= 5 a = a | 5
^= a ^= 5 a = a ^ 5
<<= a <<= 5 a = a << 5
>>= a >>= 5 a = a >> 5
>>>= a >>>= 5 a = a >>> 5

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class AssignmentOperators {
public static void main(String[] args) {
int a = 10;

a += 5; // a = a + 5
System.out.println("a += 5: " + a); // 15

a -= 3; // a = a - 3
System.out.println("a -= 3: " + a); // 12

a *= 2; // a = a * 2
System.out.println("a *= 2: " + a); // 24
}
}

三元运算符

条件运算符是Java中唯一的三元运算符

语法 条件表达式 ? 表达式1 : 表达式2条件表达式为真返回表达式1为假返回表达式2

⭐⭐ 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public class TernaryOperator {
public static void main(String[] args) {
int a = 10, b = 20;

// 使用三元运算符找出最大值
int max = (a > b) ? a : b;
System.out.println("最大值: " + max); // 20

// 判断奇偶数
String result = (a % 2 == 0) ? "偶数" : "奇数";
System.out.println(a + "是" + result); // 10是偶数
}
}

特殊运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 字符串连接运算符 (+)
// 当 `+` 运算符用于字符串时它会将其他类型的操作数转换为字符串并连接
String str = "Hello" + " " + "World"; // "Hello World"
String result = "The answer is " + 42; // "The answer is 42"


// instanceof 运算符
// 用于检查对象是否是指定类型的实例
String str = "Hello";
System.out.println("str instanceof String: " + (str instanceof String)); // true
System.out.println("str instanceof Integer: " + (str instanceof Integer)); // false


// 方法引用运算符 (::)
// Java 8 引入的方法引用用于直接引用已有方法或构造器
System.out::println; // 调用该方法 System.out.println();

运算符优先级

当表达式包含多个运算符时Java按照优先级顺序执行

优先级 运算符 运行顺序
1 `()` `[]` `.` 从左到右
2 `++` `--` `!` `~` `+` `-` `(type)` `new` 从右到左
3 `*` `/` `%` 从左到右
4 `+` `-` 从左到右
5 `<<` `>>` `>>>` 从左到右
6 `<` `<=` `>` `>=` `instanceof` 从左到右
7 `==` `!=` 从左到右
8 `&` 从左到右
9 `^` 从左到右
10 `|` 从左到右
11 `&&` 从左到右
12 `||` 从左到右
13 `? :` 从右到左
14 赋值运算符 从右到左

⭐⭐ 示例代码

1
2
int result = 10 + 5 * 2; // 先乘法后加法结果为20
int result2 = (10 + 5) * 2; // 先加法后乘法结果为30

控制结构

Java 的控制结构决定了代码的执行顺序和逻辑走向简单来说它让程序不再是一条路走到黑的顺序执行而是具备了判断分支和重复循环的能力

顺序结构

这是最简单的结构程序默认从上到下逐行执行中间没有任何判断和跳转

1
2
3
4
5
6
// 特点代码按照书写顺序依次运行
// 注意在定义变量时必须遵循前向引用原则即变量需要先声明再使用
public static void main(String[] args) {
int a = 10;
int b = a + 2;// a 变量需要先声明再使用
}

分支控制

⭐⭐ 单分支结构

    // 基本语法
    if (条件表达式) {
        // 代码块当条件表达式为 true 时执行
    }

    1.程序首先计算 条件表达式 的值
    2.如果结果为 true则执行大括号 {} 内的代码块
    3.如果结果为 false则跳过整个 if 结构执行紧跟在 if 后面的下一行代码
    4.如果代码块中只有一行语句大括号 {} 可以省略但强烈不建议省略为了代码可读性和避免错误
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
double balance = 500.0; // 账户余额
double withdraw = 800.0; // 取款金额
// 判断余额是否充足余额不足打印信息
if (withdraw > balance) {
System.out.println("余额不足取款失败");
System.out.println("当前余额: " + balance);
}
// 如果余额充足什么也不做直接执行后续业务
}

⭐⭐ 双分支结构

    // 基本语法
    if (条件表达式) {
        // 代码块1当条件为 true 时执行
    } else {
        // 代码块2当条件为 false 时执行
    }

    1.程序首先计算 条件表达式 的值
    2.如果结果为 true执行 代码块1
    3.如果结果为 false执行 代码块2
    4.执行完毕后执行紧跟在 if 后面的下一行代码
1
2
3
4
5
6
7
8
public static void main(String[] args) {
int number = 7;
if (number % 2 == 0) {
System.out.println(number + " 是偶数");
} else {
System.out.println(number + " 是奇数");
}
}

⭐⭐ 多分支结构

    // 基本语法
    if (条件表达式1) {
        // 代码块1
    } else if (条件表达式2) {
        // 代码块2
    } else {
        // 默认代码块以上条件都不满足时执行
    }

    1.自上而下依次判断条件表达式
    2.一旦遇到某个 条件表达式 为 true就执行对应的代码块执行完毕后立即跳出整个结构不再判断后续的 else if
    3.如果所有的 if 和 else if 条件都不成立且存在 else 分支则执行 else 中的代码块
    4.else 分支如果没有要处理的代码块可以省略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
int score = 85;
String grade;
if (score >= 90) {
grade = "A (优秀)";
} else if (score >= 80) {
grade = "B (良好)";
} else if (score >= 70) {
grade = "C (中等)";
} else if (score >= 60) {
grade = "D (及格)";
} else {
grade = "E (不及格)";
}
System.out.println("分数: " + score + ", 等级: " + grade);
}

⭐⭐ 嵌套分支结构

    // 基本语法
    if (外层条件表达式) {
        // 外层代码块
        if (内层条件表达式) {
            // 内层代码块 A
        } else {
            // 内层代码块 B
        }
    } else {
        // 外层代码块
    }

    1.程序首先判断外层条件只有在外层条件成立的情况下才会去执行内部的内层条件判断
    2.内层的 if-else 完全属于外层 if 或 else 的代码块范围
    3.逻辑关系通常用于表达并且的关系例如如果是男性 并且 年龄大于 18 -> 外层判断性别内层判断年龄
    4.嵌套分支结构其实就是将上述的单分支双分支或多分支结构互相包裹起来形成里外两层或多层的判断逻辑
    5.理论上 Java 支持无限层嵌套但在实际开发中为了代码的可读性和维护性建议嵌套层次不要超过 3 层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
String inputPassword = "888888";
String realPassword = "888888";
double balance = 1000.0;
double withdraw = 1500.0;

if (inputPassword.equals(realPassword)) {
System.out.println("密码正确正在验证金额...");

// 嵌套开始只有密码正确才需要验证金额
if (withdraw <= balance) {
System.out.println("取款成功请取走现金");
} else {
System.out.println("余额不足取款失败");
}
// 嵌套结束

} else {
System.out.println("密码错误卡已锁定请联系银行");
}
}

⭐⭐ 多值匹配结构

    // 基本语法
    switch (表达式) {
        case 值1:
            // 执行代码块1
            break;
        case 值2:
            // 执行代码块2
            break;
        case 值3:
        case 值4: // 多个case共用代码
            // 执行代码块3或4
            break;
        default:
            // 当所有case都不匹配时执行
    }

    1.表达式求值switch 后面括号中的表达式只会被计算一次
    2.顺序匹配从上到下依次将表达式的值与 case 后面的值进行比较一旦找到匹配的 case程序会从该处开始执行代码
    3.case 的值必须是字面量或 final 常量不能是变量或表达式
    4.break 语句用于终止 switch 结构跳出整个代码块
    5.穿透现象如果省略 break程序不会停止而是会继续执行下一个 case 或 default 的代码直到遇到 break 或 switch 结束
    6.除非刻意利用穿透否则每个 case 后都应该写 break否则会导致逻辑错误
    7.default 分支当所有 case 都不匹配时执行它是可选的位置可以放在 switch 块的任何地方但为了代码可读性强烈建议放在末尾
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
int day = 3;
switch (day) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
default:
System.out.println("周末或输入错误");
}
}

循环控制

⭐⭐ for 循环

    // 基本语法
    for (初始化语句; 循环条件; 迭代语句) {
        // 循环体重复执行的代码
    }

    1.初始化语句最先执行且只执行一次通常用于定义循环变量如 int i = 0
    2.循环条件必须是一个布尔表达式在每次循环开始前进行判断
    3.如果结果为 true则执行循环体
    4.如果结果为 false则终止循环跳出 for 结构
    5.循环体条件为 true 时执行的具体代码
    6.迭代语句在循环体执行完毕后执行通常用于更新循环变量如 i++
    7.流程顺序初始化 -> 判断条件 -> 执行循环体 -> 执行迭代语句 -> 再次判断条件……直到条件为 false
1
2
3
4
5
6
7
8
public static void main(String[] args) {
int sum = 0;
// i 从 1 开始只要 i <= 100 就继续循环每次循环后 i 自增 1
for (int i = 1; i <= 100; i++) {
sum += i; // 累加
}
System.out.println("1 到 100 的和是: " + sum);
}

⭐⭐ while 循环

    // 基本语法
    while (循环条件) {
        // 循环体
        // 迭代语句通常放在循环体末尾
    }

    1.如果条件为 true则执行循环体中的代码
    2.如果条件为 false则直接跳过整个 while 循环执行循环后面的代码
    3.注意由于是先判断如果一开始条件就是 false循环体一次都不会执行
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int sum = 0;
int i = 1;
// 只要 i <= 100 就继续循环
while (i <= 100) {
sum += i; // 累加
i++; //i 自增 1
}
System.out.println("1 到 100 的和是: " + sum);
}

⭐⭐ do-while 循环

    // 基本语法
    do {
        // 循环体
        // 迭代语句
    } while (循环条件); // 注意这里的分号不能丢

    1.先执行无论条件是否成立循环体至少会执行一次
    2.后判断执行完循环体后再判断 循环条件
    3.如果条件为 true则继续执行循环体
    4.如果条件为 false则终止循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int secret = 8;
int guess;

do {
System.out.print("请猜一个数字 (1-10): ");
guess = scanner.nextInt();
if (guess > secret) {
System.out.println("太大了再试一次");
} else if (guess < secret) {
System.out.println("太小了再试一次");
}
// 如果猜对了guess == secret循环条件为 false循环结束
} while (guess != secret);

System.out.println("恭喜你猜对了");
scanner.close();
}

⭐⭐ 循环嵌套

    // 基本语法
    for (初始化语句1; 循环条件1; 迭代语句1) {
        // 外层循环体
        for (初始化语句2; 循环条件2; 迭代语句2) {
            // 内层循环体核心逻辑通常在这里
        }
    }

    1.循环嵌套可以是任意循环forwhiledo-while的互相组合
    2.最常见的是 for 循环嵌套 for 循环
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
System.out.println("九九乘法表");
// 外层循环控制行数 (1-9行)
for (int i = 1; i <= 9; i++) {
// 内层循环控制列数 (每行打印的列数等于当前行数)
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + (i*j) + "\t");
}
System.out.println(); // 每行结束后换行
}
}

流程控制

⭐⭐ break 终止循环

1
2
3
4
5
6
7
8
9
10
11
12
13
// 一旦执行 break程序会立刻跳出当前所在的循环
// 循环中 break 后面的代码不会执行循环的迭代如 i++也会停止
public static void main(String[] args) {
// 场景寻找 1 到 10 中的第一个偶数 4
for (int i = 1; i <= 10; i++) {
if (i == 4) {
System.out.println("找到数字 4停止寻找");
break; // 循环直接结束i 不会再变成 5, 6...
}
System.out.println("正在检查数字: " + i);
}
System.out.println("循环结束后的后续代码");
}

⭐⭐ continue 跳过本次循环

1
2
3
4
5
6
7
8
9
10
11
12
// 一旦执行 continue程序会立刻跳过当前这一次循环中剩余未执行的代码
// 它不会终止整个循环而是直接去执行循环的迭代部分如 i++和条件判断准备开始下一次循环
public static void main(String[] args) {
// 场景打印 1 到 5但跳过数字 3
for (int i = 1; i <= 5; i++) {
if (i == 3) {
System.out.println("跳过数字 3");
continue; // 跳过本次剩余代码即下面的打印直接进入下一次 i=4 的循环
}
System.out.println("当前数字: " + i);
}
}

⭐⭐ return 结束方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 无论 return 写在方法的哪个角落哪怕在最深层的循环里一旦执行整个方法立刻停止
// 方法中 return 后面的所有代码都不会再执行
public class ReturnDemo {

// 有返回值的方法
public static int findNumber() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
System.out.println("找到目标数字 5直接结束方法并返回结果");
return i; // 直接跳出整个方法循环和方法后续代码都不执行了
}
System.out.println("检查数字: " + i);
}
// 如果循环正常结束都没找到返回 -1
return -1;
}

public static void main(String[] args) {
int result = findNumber();
System.out.println("方法返回的结果是: " + result);
}
}

第一阶段: 建立编程思想

Java 概述

如何快速学习Java技术Java历史Java特点SublimeJava运行机制JDK转义字符Java开发规范Java API

变量

数据类型变量基本使用数据类型转换

运算符

运算符介绍算术运算符关系运算符逻辑运算符赋值运算符三元运算符优先级二进制位运算符

控制结构

顺序分支(if else switch)循环(for , while , do while)breakcontinuereturn

数组排序和查找

数组排序查找

面向对象编程(基础)

类与对象成员方法成员方法传参机制overload可变参数作用域构造器this

面向对象编程(中级)

访问修饰符封装继承多态SuperoverwriteObject类详解断点调试

第二阶段: 提升编程能力

面向对象编程(高级)

类变量和类方法理解main方法语法代码块单例设计模式final 关键字抽象类接口内部类

枚举和注解

自定义类实现枚举enum关键字实现枚举JDK内置的基本注解类型元注解:对注解进行注解

Exception

异常的概念异常体系图常见的异常异常处理自定义异常throw和throws的对比

常用类

包装类StringStringBufferStringBuilderMathDateCalendarLocalDate…SystemArraysBiglntegerBigDecimal

集合

  • 集合框架体系
  • Collection
    • ListArrayListLinkedListVector
    • SetHashSetLinkedHashSetTreeSet
  • MapHashMapHashtableLinkedHashMapTreeMapProperties
  • Collections

泛型

  • 泛型语法
  • 自定义泛型泛型类泛型接口泛型方法
  • 泛型继承和通配符

线程基础

线程介绍线程使用线程方法线程生命周期Synchronized互斥锁死锁

IO流

  • 文件概念常用操作
  • IO流原理及流的分类
  • 节点流和处理流
  • 输入流
    • InputStreamFilelnputStreamBufferedInputStreamObjectlnputStream
    • ReaderFileReaderBufferedReaderInputStreamReader
  • 输出流
    • OutputStreamFileOutputStreamBufferedOutputStreamObjectOutputStream
    • WriterFileWriterBufferedWriterOutputStreamWriter
  • Properties类

Java8新特性

Lambda函数式接口接口静态方法接口默认方法方法引用构造器引用stream API并行流串行流Optional新时间日期 API

Java11 新特性

  • 代码层面新特性JShell类型推断集合增强APIStkeam 加强新增字符串处理方法Optional 加强InputStream增强API标准Java异步HTTP客户端
  • 其他新特性简化的编译运行支持Unicode 10Epsilon垃圾收集器ZGCJFR支持Linux容器支持G1上的并行完全垃圾收集增加加密算法,代替RC4最新HTTPS安全协议TLS 1.3移除和废弃的内容

第三阶段: 分析需求代码实现

网络编程

网络基础InetAddressSocketTCP编程字节流字符流UDP编程

反射

反射机制Class类类的加载ClassFieldMethodConstructor访问属性访问方法

Mysql基础

  • MySQL安装和配置
  • 数据库创建查看删除数据库备份恢复数据库
  • 创建删除修改查询
  • Mysql数据类型
  • CRUDInsertUpdateDeleteSelect
  • 函数统计函数时间日期字符串函数数学函数流程控制
  • 内连接
  • 外连接
  • 约束not nullprimary keyuniqueforeign keycheck自增长
  • 索引主键索引唯一索引(UNIQUE)普通索引(INDEX)全文索引
  • 事务

JDBC和连接池

  • JDBC概述
  • JDBC快速入门
  • JDBC APIPreparedStatementDriverManagerStatementResultSet
  • JDBCUtils
  • 事务
  • 批处理
  • 连接池DataSourceDBCPC3P0ProxoolBoneCPDruid
  • Apache-DBUtils
  • DAO增删改查-BasicDao

正则表达式

  • 快速入门
  • 正则表达式基本语法
  • 三个常用类PatternMatcherPatternSyntaxException
  • 分组捕获反向引用
  • 元字符限定符选择匹配符分组组合和反向引用符特殊字符字符匹配符定位符

学习资源

  • 视频
    • 韩顺平零基础 30 天学会 Javahttps://www.bilibili.com/video/BV1fh411y7R8
    • 宋红康全网最全Java零基础入门教程https://www.bilibili.com/video/BV1Kb411W75N
    • JDK8新特性详解https://www.bilibili.com/video/BV1k64y1R7sA
    • Java 核心技术卷https://www.bilibili.com/video/BV18u411q7jv
  • 文档
    • 菜鸟教程 Javahttps://www.runoob.com/java/java-tutorial.html
    • 菜鸟教程 Java 8https://www.runoob.com/java/java8-new-features.html
    • 廖雪峰 Java 教程https://www.liaoxuefeng.com/wiki/1252599548343744
    • Java API 中文文档https://www.matools.com/api/java8
  • 书籍
    • Head First Java
    • Java 8 实战
    • Java 从入门到精通
    • Java 核心技术卷 Ihttps://pan.baidu.com/s/1G36MF1XrLhKMaBpNcfM61g?pwd=ep11
  • 工具
    • 在线编写运行https://c.runoob.com/compile/10/
  • 游戏
    • Codegymhttps://codegym.cc/zh
  • 练手项目
    • 牛客题库https://www.nowcoder.com/intelligentTest
    • Java 实现简单计算器https://www.lanqiao.cn/courses/185
    • Eclipse 实现 Java 编辑器https://www.lanqiao.cn/courses/287
    • 一本糊涂账https://how2j.cn/module/104.html
    • Java 五子棋https://blog.csdn.net/cnlht/article/details/8176130
    • Java 中国象棋https://blog.csdn.net/cnlht/article/details/8205733
    • JAVA GUI 图书馆管理系统https://github.com/uboger/LibraryManager
    • JAVA 坦克大战小游戏https://github.com/wangzhengyi/TankWar
    • Swing 编写的俄罗斯方块https://github.com/HelloClyde/Tetris-Swing
    • 小小记账本https://github.com/xenv/SmallAccount