2026最新 Java 学习全攻略:从入门到精通的详细指南,收藏这篇就够了!!!
本文包含Java 基础语法、面向对象、常用 API、集合、IO、多线程、反射注解、泛型、网络编程、JDBC 数据库全套核心知识点。
一、Java 入门与环境搭建
1.1 什么是 Java
Java 是一门跨平台、面向对象、安全、稳定、支持多线程的编程语言。
通俗理解:
- 跨平台:一次编写,Windows、Linux、Mac 都能运行
- 面向对象:代码结构清晰、好维护、好扩展
- 安全:没有指针,不会随便访问内存
- 稳定:自带自动内存管理(垃圾回收),程序不容易崩溃
- 用途:企业后端、安卓 App、大数据、游戏服务器、银行系统都在用
1.2 JDK、JRE、JVM 的区别
JVM(Java 虚拟机)
真正执行 Java 代码的程序。
- 读取编译后的
.class字节码 - 不同系统对应不同 JVM,是跨平台的核心
JRE(Java 运行环境)
运行 Java 程序必备。
- JRE = JVM + Java 核心类库(String、ArrayList 等)
- 只负责运行,不能写代码
JDK(Java 开发工具包)
开发 Java 程序必备。
- JDK = JRE + 编译器 + 调试工具
- 用来写代码、编译、调试
一句话总结:开发用 JDK,运行用 JRE,真正干活的是 JVM。
1.3 开发环境搭建
1.3.1 下载 JDK
推荐长期支持版:Java 8、11、17。
1.3.2 安装
双击安装包,一路“下一步”,记住安装路径。
1.3.3 配置环境变量
- JAVA_HOME:填写 JDK 安装目录
- Path:添加
%JAVA_HOME%\bin
1.3.4 验证
打开命令提示符(cmd)输入:
java -version
javac
输出版本号,说明配置成功。
1.4 第一个 Java 程序:HelloWorld
代码
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
简单解释
public class HelloWorld:定义公共类,文件名必须一致main:程序入口,Java 必须有System.out.println:控制台打印内容
编译运行
- 保存为
HelloWorld.java - 编译:
javac HelloWorld.java
- 运行:
java HelloWorld
结果
Hello World!
1.5 Java 程序运行原理
完整流程:
- 编写
.java源代码 javac编译 → 生成.class字节码- JVM 加载
.class - JVM 执行程序
一句话:人写 .java,编译器转 .class,虚拟机执行。
1.6 IDEA 基本使用
1.6.1 新建项目
File → New Project → 选择 Java → 选已安装的 JDK
1.6.2 新建类
public Demo {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
二、Java 语法基础
2.1 标识符
标识符:给类、方法、变量、包、接口起名字。
命名规则
- 只能由字母、数字、下划线
_、美元符$组成 - 不能以数字开头
- 不能是关键字
- 区分大小写
命名规范
- 类:大驼峰
HelloWorld - 变量/方法:小驼峰
userName - 常量:全大写
MAX_SIZE
示例
int age;
String userName;
public class Student {}
2.2 关键字
关键字:Java内置、有特殊含义、不能当标识符。
常用关键字
- 访问:
public private protected - 类:
class interface enum - 方法:
static void return - 流程:
if else for while switch break continue - 异常:
try catch finally throw throws - 对象:
new this super - 类型:
int double boolean char
示例
// 关键字不能当变量名
// int class; 错误
int num; // 正确
2.3 注释
单行注释
// 我是单行注释
int a = 10;
多行注释
/*
我是多行注释
可以写很多行
*/
int b = 20;
文档注释
/**
* 文档注释:用于生成API文档
*/
public void test(){}
2.4 数据类型
2.4.1 基本数据类型(8种)
byte:-128~127short:短整型int:整型(最常用)long:长整型float:单精度小数double:双精度小数(常用)char:字符boolean:true/false
示例
byte b = 10;
int i = 100;
long l = 1000L;
double d = 3.14;
char c = 'A';
boolean flag = true;
2.4.2 引用数据类型
- 类、接口、数组、字符串
String str = "Java";
int[] arr = new int[5];
2.4.3 类型转换
自动转换(小→大)
int a = 10;
double b = a;
强制转换(大→小)
double d = 3.9;
int i = (int) d;
2.5 变量与常量
变量
值可改变
int age = 18;
age = 20;
常量
值不可变,用final
final int MAX = 100;
变量作用域
- 局部:方法内
- 成员:类内、方法外
2.6 运算符
算术
int a=10, b=3;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
System.out.println(a%b);
a++; b--;
赋值
int a=10;
a += 5;
a -= 3;
比较
System.out.println(10 == 5);
System.out.println(10 != 5);
System.out.println(10 > 5);
逻辑
true && false;
true || false;
!true;
三元
int max = a > b ? a : b;
2.7 流程控制
if
if (age >= 18) {
System.out.println("成年");
}
if-else
if (age >= 18) {
System.out.println("成年");
} else {
System.out.println("未成年");
}
switch
int num=2;
switch (num) {
case 1: System.out.println("一"); break;
case 2: System.out.println("二"); break;
default: System.out.println("其他");
}
for
for (int i=0; i<5; i++) {
System.out.println(i);
}
while
int i=0;
while (i<5) {
System.out.println(i);
i++;
}
break / continue
for (int i=0; i<10; i++) {
if (i==5) break;
if (i==3) continue;
System.out.println(i);
}
2.8 数组
一维数组
int[] arr = {1,2,3};
for (int num : arr) {
System.out.println(num);
}
二维数组
int[][] arr = {{1,2},{3,4}};
Arrays工具类
import java.util.Arrays;
Arrays.sort(arr);
三、面向对象编程(OOP)
3.1 面向对象三大特性
封装
把**数据(成员变量)和方法(行为)**打包到类里,对外只暴露必要的方法,隐藏内部细节。
好处:安全、可控、易维护。
继承
子类继承父类,复用父类代码,扩展新功能。
好处:代码复用、减少重复、易扩展。
多态
同一行为,不同实现。
好处:灵活、可扩展、解耦。
3.2 类与对象
类
模板、蓝图,定义属性和行为。
public class Person {
// 属性
String name;
int age;
// 行为
public void sayHello() {
System.out.println("你好!");
}
}
对象
类的实例、具体事物,new 出来。
public class Test {
public static void main(String[] args) {
// 创建对象
Person p = new Person();
// 赋值
p.name = "张三";
p.age = 20;
// 调用方法
p.sayHello();
}
}
3.3 构造方法
创建对象时自动调用,用于初始化。
特点:
- 名字和类名完全一样
- 没有返回值
- 可重载
public class Person {
String name;
int age;
// 无参构造
public Person() {
name = "未知";
age = 0;
}
// 有参构造(重载)
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
3.4 this 关键字
代表当前对象。
用途:
- 区分成员变量和局部变量
- 调用本类构造方法
public class Person {
String name;
public void setName(String name) {
// this.name:成员变量
// name:局部变量
this.name = name;
}
}
3.5 封装
隐藏数据,通过方法访问。
用 private 修饰成员变量,提供 get/set 方法。
public class Person {
// 私有成员,外部不能直接访问
private String name;
private int age;
// 获取
public String getName() {
return name;
}
// 设置
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) { // 加校验
this.age = age;
}
}
}
3.6 继承
子类继承父,复用代码。
关键字:extends
// 父类
public class Person {
String name;
public void say() {
System.out.println("人会说话");
}
}
// 子类 Student 继承 Person
public class Student extends Person {
// 扩展自己的属性和方法
int score;
public void study() {
System.out.println("学生学习");
}
}
3.7 方法重写
子类重写父类方法,改变实现。
条件:方法名、参数、返回值必须一样,加 @Override 注解。
public class Student extends Person {
@Override
public void say() {
System.out.println("学生说:好好学习");
}
}
3.8 super 关键字
代表父类对象。
用途:
- 调用父类构造
- 调用父类方法
public class Student extends Person {
public Student() {
super(); // 调用父类无参构造
}
@Override
public void say() {
super.say(); // 调用父类方法
System.out.println("学生自己说");
}
}
3.9 多态
方法重载
同一类中,方法名相同,参数不同。
public class Demo {
public void add(int a) {}
public void add(int a, int b) {}
}
向上转型
父类引用指向子类对象。
Person p = new Student();
p.say(); // 调用子类重写方法
向下转型
子类引用指向父类对象(强转)。
Student s = (Student) p;
instanceof
判断对象类型。
if (p instanceof Student) {
Student s = (Student) p;
}
3.10 抽象类
不能实例化,有抽象方法。
关键字:abstract
public abstract class Animal {
// 抽象方法:无实现,子类必须重写
public abstract void eat();
}
3.11 接口
规范、标准,全是抽象方法。
关键字:interface、implements
public interface Run {
void run();
}
public class Person implements Run {
@Override
public void run() {
System.out.println("人跑步");
}
}
3.12 static 关键字
属于类,不属于对象。
public class Demo {
// 静态变量
public static int count;
// 静态方法
public static void test() {}
// 静态代码块
static {
System.out.println("静态代码块");
}
}
3.13 final 关键字
最终、不可变。
- 修饰类:不能被继承
- 修饰方法:不能重写
- 修饰变量:常量,不可改
final int MAX = 100;
3.14 内部类
成员内部
public class Outer {
class Inner {}
}
匿名内部
new Runnable() {
public void run() {}
};
3.15 包与导入
管理类,避免重名。
package com.test;
import java.util.ArrayList;
3.16 代码块
构造代码块
{
System.out.println("构造代码块");
}
静态代码块
static {
System.out.println("静态代码块");
}
四、异常处理
4.1 异常体系
异常(Exception):程序运行时出现的不正常情况,导致代码中断。
异常的总父类:Throwable
- Error(错误):严重、不可处理,如内存溢出、虚拟机崩溃。
- Exception(异常):可处理,分为:
- 编译时异常(受检异常):必须处理,如文件找不到、网络异常。
- 运行时异常(非受检异常):运行才报错,可处理可不处理,如空指针、数组越界。
4.2 try-catch-finally
捕获并处理异常。
格式
try {
// 可能出错的代码
} catch (异常类型 e) {
// 处理异常
} finally {
// 无论是否出错,一定会执行
}
示例
public class ExceptionDemo {
public static void main(String[] args) {
try {
int a = 10 / 0; // 除零异常
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} finally {
System.out.println("程序结束");
}
}
}
4.3 throws 关键字
声明方法可能抛出异常,交给调用者处理。
示例
public void readFile() throws Exception {
// 可能出错的代码
}
4.4 throw 关键字
手动抛出异常对象。
示例
public void checkAge(int age) {
if (age < 18) {
throw new RuntimeException("未成年不能访问");
}
}
4.5 自定义异常
自己定义异常类,用于业务错误。
步骤
- 继承
Exception(编译时)或RuntimeException(运行时) - 提供构造方法
示例
// 自定义运行时异常
public class AgeException extends RuntimeException {
public AgeException(String message) {
super(message);
}
}
// 使用
public void checkAge(int age) {
if (age < 18) {
throw new AgeException("年龄太小");
}
}
五、常用 API
5.1 String(字符串)
字符串不可变,每次修改都会生成新对象。
常用方法
String str = " JavaStudy ";
// 1. 获取长度
int len = str.length();
// 2. 去除首尾空格
String trimStr = str.trim();
// 3. 比较内容(区分大小写)
boolean eq = "java".equals(str);
// 4. 比较内容(忽略大小写)
boolean eqIgnoreCase = "java".equalsIgnoreCase(str);
// 5. 截取子串
String sub = str.substring(2, 6);
// 6. 分割字符串
String[] arr = str.split(" ");
// 7. 替换
String rep = str.replace("a", "A");
// 8. 转大小写
String upper = str.toUpperCase();
String lower = str.toLowerCase();
// 9. 查找索引
int idx = str.indexOf("S");
5.2 StringBuilder / StringBuffer
可变字符串,适合频繁拼接。
- StringBuilder:非线程安全、效率高(常用)
- StringBuffer:线程安全、效率低
示例
StringBuilder sb = new StringBuilder();
// 拼接
sb.append("Hello");
sb.append(" ");
sb.append("Java");
// 反转
sb.reverse();
// 转为String
String str = sb.toString();
5.3 包装类
把基本类型变成对象,支持自动装箱/拆箱。
8 种对应关系
Integer→intDouble→doubleBoolean→booleanCharacter→charByte/Short/Long/Float
自动装箱 / 拆箱
// 装箱:int → Integer
Integer a = 10;
// 拆箱:Integer → int
int b = a;
常用方法
// 字符串转int
int num = Integer.parseInt("123");
// int转字符串
String str = Integer.toString(456);
5.4 日期相关 API
5.4.1 传统日期(Date、SimpleDateFormat、Calendar)
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
// Date:当前时间
Date date = new Date();
// SimpleDateFormat:格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = sdf.format(date);
// Calendar:日期计算
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 7); // 加7天
5.4.2 Java 8 新日期(推荐、线程安全)
import java.time.*;
import java.time.format.DateTimeFormatter;
// 本地日期
LocalDate localDate = LocalDate.now();
// 本地时间
LocalTime localTime = LocalTime.now();
// 日期+时间
LocalDateTime ldt = LocalDateTime.now();
// 格式化
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str = ldt.format(dtf);
5.5 System、Math、Random
System
// 当前时间戳(毫秒)
long time = System.currentTimeMillis();
// 退出程序
// System.exit(0);
Math
// 绝对值
Math.abs(-5);
// 最大值
Math.max(3, 9);
// 随机数 [0,1)
double r = Math.random();
// 四舍五入
Math.round(3.6);
Random
import java.util.Random;
Random r = new Random();
int num = r.nextInt(10); // 0~9
5.6 Object 类
所有类的父类,默认继承。
常用方法
// 比较地址
obj.equals(o);
// 哈希值
obj.hashCode();
// 转字符串
obj.toString();
六、集合框架
6.1 集合体系结构
集合是用来存储多个数据的容器,比数组更灵活、功能更强。
- Collection:单列集合,一次存一个元素
- List:有序、可重复
- Set:无序、不可重复
- Map:双列集合,以**键值对(key-value)**形式存储
6.2 List 接口
特点:有序、可重复、有索引
6.2.1 ArrayList
- 底层:数组
- 优点:查询快
- 缺点:增删慢
import java.util.ArrayList;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 添加
list.add("Java");
list.add("Python");
list.add("C++");
// 获取
String s = list.get(0);
// 遍历
for (String str : list) {
System.out.println(str);
}
// 删除
list.remove(1);
// 大小
int size = list.size();
}
}
6.2.2 LinkedList
- 底层:双向链表
- 优点:增删快
- 缺点:查询慢
import java.util.LinkedList;
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.addFirst("First");
linkedList.removeLast();
6.3 Set 接口
特点:无序、不可重复、无索引
6.3.1 HashSet
- 底层:哈希表
- 去重原理:hashCode() + equals()
import java.util.HashSet;
import java.util.Set;
Set<String> set = new HashSet<>();
set.add("张三");
set.add("李四");
set.add("张三"); // 重复,添加失败
// 遍历
for (String s : set) {
System.out.println(s);
}
6.3.2 TreeSet
- 底层:红黑树
- 特点:自动排序
import java.util.TreeSet;
TreeSet<Integer> ts = new TreeSet<>();
ts.add(3);
ts.add(1);
ts.add(2);
// 结果:[1,2,3]
6.4 Map 接口
特点:存储键值对,key 不可重复,value 可重复
6.4.1 HashMap
- 底层:哈希表
- 最常用
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
// 添加
map.put("张三", 20);
map.put("李四", 22);
// 获取
int age = map.get("张三");
// 遍历(键值对)
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 判断key是否存在
boolean exists = map.containsKey("张三");
}
}
6.5 Collections 工具类
专门用来操作Collection 集合的工具类
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
// 排序
Collections.sort(list);
// 反转
Collections.reverse(list);
// 最大值
int max = Collections.max(list);
6.6 Java 8 Stream 流
对集合进行高效、简洁的批量操作(过滤、统计、排序、收集)
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C");
list.add("JavaScript");
// 1. 过滤:长度大于3
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
// 2. 转大写
List<String> upperList = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// 3. 计数
long count = list.stream().count();
七、IO 与 NIO
7.1 IO 概述
IO(输入/输出):用于读写文件、网络传输、控制台交互。
- 字节流:处理一切文件(图片、视频、文本)
- 字符流:只处理纯文本(.txt、.java)
7.2 字节流(InputStream / OutputStream)
文件字节流
import java.io.FileInputStream;
import java.io.FileOutputStream;
// 读文件
FileInputStream fis = new FileInputStream("test.txt");
int data = fis.read(); // 读一个字节
fis.close();
// 写文件
FileOutputStream fos = new FileOutputStream("test.txt");
fos.write(97); // 写一个字节(a)
fos.close();
7.3 字符流(Reader / Writer)
文件字符流
import java.io.FileReader;
import java.io.FileWriter;
// 读文本
FileReader fr = new FileReader("test.txt");
int ch = fr.read();
fr.close();
// 写文本
FileWriter fw = new FileWriter("test.txt");
fw.write("Hello IO");
fw.close();
7.4 缓冲流(高效读写)
包装普通流,带缓冲区,速度快。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
// 缓冲字符流
BufferedReader br = new BufferedReader(new FileReader("test.txt"));
String line = br.readLine(); // 读一行
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
bw.write("一行文字");
bw.newLine(); // 换行
bw.close();
7.5 File 类(文件/目录操作)
import java.io.File;
File file = new File("test.txt");
// 判断
file.exists();
file.isFile();
file.isDirectory();
// 创建/删除
file.createNewFile();
file.delete();
// 目录
File dir = new File("myFolder");
dir.mkdir();
7.6 NIO(Java 新IO,非阻塞)
Path、Files
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("test.txt");
// 读
String content = Files.readString(path);
// 写
Files.write(path, "NIO 写入".getBytes());
Channel、Buffer
NIO 核心:通道 + 缓冲区。
7.7 序列化
把对象 → 字节流,用于保存对象、网络传输。
import java.io.Serializable;
// 实现Serializable接口
class User implements Serializable {
String name;
int age;
}
ObjectOutputStream / ObjectInputStream
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"));
oos.writeObject(new User("张三", 20));
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"));
User u = (User) ois.readObject();
7.8 transient 关键字
序列化时忽略该字段。
transient String password;
八、多线程
8.1 进程与线程
- 进程:独立运行的程序,资源分配单位
- 线程:进程内的执行单元,CPU调度单位
- 一个进程可以包含多个线程,并发执行、提高效率
8.2 线程生命周期
新建 → 就绪 → 运行 → 阻塞 → 死亡
8.3 线程创建方式
方式一:继承 Thread 类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行");
}
}
// 启动
new MyThread().start();
方式二:实现 Runnable 接口(推荐)
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable线程");
}
}
new Thread(new MyRunnable()).start();
方式三:Lambda(简化)
new Thread(() -> {
System.out.println("Lambda线程");
}).start();
方式四:Callable(有返回值)
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "线程返回结果";
}
}
FutureTask<String> task = new FutureTask<>(new MyCallable());
new Thread(task).start();
String res = task.get();
8.4 线程常用方法
Thread t = new Thread();
t.start(); // 启动线程
t.sleep(1000); // 休眠1秒
t.join(); // 等待线程执行完毕
t.yield(); // 让出CPU
t.interrupt(); // 中断线程
8.5 线程安全问题
多个线程同时操作共享数据,会出现数据错乱。
解决:synchronized 同步
// 同步方法
public synchronized void add() {
count++;
}
// 同步代码块
synchronized (对象) {
count++;
}
Lock 锁(更灵活)
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Lock lock = new ReentrantLock();
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
8.6 线程通信
wait() / notify() / notifyAll()
synchronized (obj) {
obj.wait(); // 等待,释放锁
obj.notify(); // 唤醒一个线程
}
8.7 线程池
复用线程、避免频繁创建销毁。
常用线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// 固定线程池
ExecutorService pool = Executors.newFixedThreadPool(3);
pool.submit(() -> {
System.out.println("线程池任务");
});
pool.shutdown();
8.8 并发工具
- CountDownLatch:等待多线程完成
- CyclicBarrier:线程屏障
- Semaphore:控制并发数
8.9 并发集合
- ConcurrentHashMap:线程安全Map
- CopyOnWriteArrayList:线程安全List
九、反射与注解
9.1 反射(Reflection)
反射:程序运行时,动态获取/操作类、对象、方法、属性。
一句话:运行时看透类的所有信息,甚至私有。
9.1.1 获取 Class 对象(三种方式)
// 1. 类名.class
Class<?> clazz1 = Person.class;
// 2. 对象.getClass()
Person p = new Person();
Class<?> clazz2 = p.getClass();
// 3. Class.forName("全类名")(最常用)
Class<?> clazz3 = Class.forName("com.example.Person");
9.1.2 通过反射创建对象
Class<?> clazz = Person.class;
// 无参构造
Person p = (Person) clazz.newInstance();
// 有参构造
Constructor<?> con = clazz.getConstructor(String.class, int.class);
Person p2 = (Person) con.newInstance("张三", 20);
9.1.3 反射操作成员变量
Class<?> clazz = Person.class;
Person p = new Person();
// 获取私有字段
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 暴力破解,取消私有
field.set(p, "李四"); // 赋值
String name = (String) field.get(p); // 取值
9.1.4 反射调用方法
Class<?> clazz = Person.class;
Person p = new Person();
// 获取方法
Method method = clazz.getDeclaredMethod("sayHello");
method.invoke(p); // 调用方法
// 带参数方法
Method setAge = clazz.getDeclaredMethod("setAge", int.class);
setAge.invoke(p, 25);
9.2 注解(Annotation)
注解:给代码打标记,编译器/程序可以读取。
分为:内置注解、元注解、自定义注解。
9.2.1 内置注解(常用)
@Override // 重写
@Deprecated // 过时
@SuppressWarnings // 抑制警告
9.2.2 元注解(修饰注解的注解)
@Target // 注解作用位置:类、方法、字段
@Retention // 生命周期:源码、class、运行时
@Documented // 生成文档
@Inherited // 可被继承
9.2.3 自定义注解
import java.lang.annotation.*;
// 自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
int age() default 18;
}
9.2.4 使用注解
@MyAnnotation(value = "测试", age = 20)
public class Demo {
@MyAnnotation("方法注解")
public void test(){}
}
9.2.5 反射读取注解
Class<?> clazz = Demo.class;
MyAnnotation anno = clazz.getAnnotation(MyAnnotation.class);
System.out.println(anno.value());
十、泛型
10.1 泛型概念
泛型可以在编译阶段约束数据类型,把类型校验提前,避免类型转换异常,同时复用代码。使用尖括号<>定义类型参数,统一规范容器存储的数据类型。
10.2 泛型类
定义类时指定未知类型,实例化时确定具体类型
// 定义泛型类
public class Box<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
// 使用泛型类
public class Test {
public static void main(String[] args) {
Box<String> strBox = new Box<>();
strBox.setData("Java泛型");
String res = strBox.getData();
Box<Integer> intBox = new Box<>();
intBox.setData(666);
}
}
10.3 泛型方法
方法定义独立的泛型参数,适配不同类型参数
public class GenericMethod {
// 泛型方法
public <E> E getElement(E element){
return element;
}
public static void main(String[] args) {
GenericMethod gm = new GenericMethod();
String s = gm.getElement("字符串");
Integer num = gm.getElement(100);
}
}
10.4 泛型接口
接口中声明泛型,实现类确定具体类型
// 泛型接口
public interface IGeneric<T> {
void show(T t);
}
// 实现类指定具体类型
class StringImpl implements IGeneric<String>{
@Override
public void show(String s) {
System.out.println(s);
}
}
10.5 泛型通配符
无边界通配符 ?
代表任意未知类型,只能读取数据,不能写入
import java.util.ArrayList;
import java.util.List;
public class WildcardDemo {
public static void printList(List<?> list){
for (Object obj : list) {
System.out.println(obj);
}
}
public static void main(String[] args) {
List<String> strList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
printList(strList);
printList(intList);
}
}
上限通配符 ? extends T
限定类型只能是T本身或者T的子类
// 只能接收Animal及子类集合
public void getAnimal(List<? extends Animal> list){}
下限通配符 ? super T
限定类型只能是T本身或者T的父类
// 只能接收Dog及父类集合
public void setDog(List<? super Dog> list){}
10.6 泛型擦除
编译阶段泛型生效,编译完成后会抹去泛型标识,统一转为Object类型,运行阶段不存在泛型类型
- 基本数据类型不能作为泛型参数,只能使用包装类
- 无法使用泛型直接创建数组实例
- 不同泛型参数的同类对象,运行时视为同一个类型
补充第十一章 网络编程
十一、网络编程
11.1 网络编程基础
网络编程用于实现设备之间的数据交互,核心依托IP地址定位主机、端口号定位程序、协议规范传输规则。
- IP地址:区分网络中不同计算机
- 端口号:0-65535,标识设备上运行的应用程序
- 常用协议:TCP可靠连接传输、UDP无连接快速传输
11.2 InetAddress 地址类
用于获取本机、远端主机IP与主机名
import java.net.InetAddress;
public class InetDemo {
public static void main(String[] args) throws Exception {
// 获取本机地址
InetAddress local = InetAddress.getLocalHost();
System.out.println(local.getHostAddress());
// 根据域名获取地址
InetAddress remote = InetAddress.getByName("www.baidu.com");
}
}
11.3 TCP通信
面向连接、可靠稳定、三次握手建立通道,适用于文件传输、网页数据交互
客户端
import java.io.OutputStream;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) throws Exception {
// 绑定服务端IP和端口
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream os = socket.getOutputStream();
os.write("TCP客户端消息".getBytes());
socket.close();
}
}
服务端
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws Exception {
// 监听指定端口
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
server.close();
}
}
11.4 UDP通信
无连接、数据以数据包形式发送,速度快但不可靠,适用于直播、语音通话
发送端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UdpSend {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
byte[] data = "UDP数据报文".getBytes();
InetAddress ip = InetAddress.getLocalHost();
// 封装数据包
DatagramPacket packet = new DatagramPacket(data,data.length,ip,9999);
socket.send(packet);
socket.close();
}
}
接收端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpReceive {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf,buf.length);
socket.receive(packet);
System.out.println(new String(buf,0,packet.getLength()));
socket.close();
}
}
11.5 URL网络访问
通过统一资源定位符,读取网络网页资源数据
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
public class UrlDemo {
public static void main(String[] args) throws Exception {
URL url = new URL("https://www.baidu.com");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}
}
十二、JDBC数据库编程
12.1 JDBC概述
JDBC是Java操作数据库的标准接口,通过固定规范实现Java程序增删改查MySQL、Oracle等数据库,实现程序与数据持久化交互。
12.2 核心使用步骤
- 导入数据库驱动包
- 加载驱动类
- 获取数据库连接
- 创建执行SQL对象
- 执行语句,处理结果
- 关闭资源
12.3 基础连接与查询示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
// 1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.数据库连接参数
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false";
String user = "root";
String password = "123456";
// 3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
// 4.创建执行对象
Statement stmt = conn.createStatement();
// 5.执行查询
String sql = "select * from user";
ResultSet rs = stmt.executeQuery(sql);
// 遍历结果集
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("name"));
}
// 6.关闭资源
rs.close();
stmt.close();
conn.close();
}
}
12.4 增删改操作
// 插入数据
String insertSql = "insert into user(name,age) values('小明',20)";
int rows = stmt.executeUpdate(insertSql);
System.out.println("影响行数:"+rows);
// 修改数据
String updateSql = "update user set age=21 where name='小明'";
stmt.executeUpdate(updateSql);
// 删除数据
String delSql = "delete from user where name='小明'";
stmt.executeUpdate(delSql);
12.5 PreparedStatement预编译对象
防止SQL注入,执行效率更高,推荐日常使用
import java.sql.PreparedStatement;
String sql = "select * from user where id=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1,1);
ResultSet rs = pstmt.executeQuery();
12.6 事务管理
多条SQL要么全部执行成功,要么全部回滚,保证数据一致性
try {
conn.setAutoCommit(false); // 关闭自动提交
// 执行多条数据库操作
conn.commit(); // 提交事务
} catch (Exception e) {
conn.rollback(); // 异常回滚
}
更多推荐
所有评论(0)