Java基础
JDK,JRE,JVM
- JDK:Java开发者工具
- JRE:Java运行环境
- JVM:Java虚拟机
运行过程
- 编译与解释
- 编译:对文件整体翻译为另一种语言(无执行,输出另一语言代码)
- 解释:对文件逐句翻译并逐句执行(有执行,输出运行结果)
- Java执行过程
- 源文件(.java)➡JVM➡字节码(.class)➡类装载器➡字节码校验器➡解释器
( 编译 ) ( 运行 )
- 编译:(CMD) javac 文件名.java (编译成 .class文件)
- 运行:(CMD) java 文件名.class(运行并输出结果)
结构
- 修饰符
- 权限修饰符
private | protected | public | |
本类 | 可见 | 可见 | 可见 |
同包 | 不可见 | 可见 | 可见 |
不同包 | 不可见 | 不可见 | 可见 |
-
- 静态修饰符(static)
- 调用
- 类名 . 静态成员
- 属于类所有,便于共享
- 修饰属性
- 对应数据被该类的所有实例化对象所共享,发生修改时,所有对象关于这个属性的值都被修改
- 修饰代码块
- 类被执行时,静态代码块首先执行,且只执行一次
- 修饰方法
- 调用
- 返回值修饰符
- 静态修饰符(static)
- 关键字
- final
- 修饰变量则变量值不可被改变
- 修饰方法则方法不可被重写
- 修饰类则类不可被继承
- final
- 变量(值一直变的数据对应的内存空间)
- 成员变量:类的属性
- 静态变量:由 static 修饰,有效范围可以跨类
- 局部变量:方法的属性
- 成员变量与局部变量具有相同变量名时,成员变量失效
- 声明
- 赋值声明
- 不赋值声明
- 成员变量:类的属性
- 常量(值不变的数据对应的内存空间)
- 必须在声明时就设定初值
- 声明
- final 数据类型 常量名
运算符
- 运算符
- a++(先赋值后+1)++a(先+1后赋值)
- 位运算
- 与(&):全一为一
- 或( | ):有一为一
- 异或(^):同零异一
- 取反(~)
- <<(左移)>>(右移)(算术运算)
- <<<(无符号左移)>>>(无符号右移)(逻辑运算)
- 条件运算符
- (" " + int + int)时后方变量当字符串处理
- (int + int + " ")时正常运算
- 三元运算符
- x ? y :z( x 为 true 时,结果为 y ,反之为 z )
数据类型
- 基本数据类型
- 整形
- byte,short,int,long(后加 L / l )
- 浮点型
- double,float(后加 F / f )
- 字符型
- char(存储单字符,' ' 表示)
- 布尔型
- boolean(默认值为 false )
- 转义字符
- 以 \ 开头( \r 回车,\n 换行,\f 换页,\b 退格)
- 整形
- 引用数据类型:类,接口,数组
- 进制类型:
- 二进制:0b
- 八进制:0
- 十六进制:0x
- 类型转换
- 优先级(精度)
double > float > long > int > short > byte
-
- 隐式转换(系统自动执行):低级类型(小精度) ➡ 高级类型(大精度)
- 显示转换(强制类型转换):高级类型(大精度) ➡ 低级类型(小精度)
数组——相同数据类型的有序集合
- 数组本身也是对象,存放在堆中(Java中对象存放在堆中)
- 声明
-
- dataType[] 数组名;
- dataType 数组名[];
- 使用
-
- 遍历数组:for( int array : 数组名 )
- 替换数组元素
- fill( int[] a , int value ) //数组 a 的所有值替换为 value
- fill( int[] a , int fromindex , int toindex , int value ) //数组 a 中从 fromindex 到 toindex 之间的元素替换为 value
- 排序
- Arrays.sort( 数组名 )
- 复制
- copyOf( 数组名 , int newlength ) //复制数组到指定长度
- copyOfRange( 数组名 , int fromindex , int toindex ) //复制指定长度的数组
- 查询
- binarySearch( Object[] 数组名 , Object Key ) //搜索指定值 key,并返回在数组中的位置 (二分法搜索)
- binarySearch( Object[] 数组名 , int fromindex , int toindex , Object Key ) //搜索指定范围内的指定值 key,并返回在数组中的位置 (范围包含 fromindex 不包含 toindex)
流程控制
用户交互Scanner
- next():必须存在有效字符串,有效字符前空白自动去除,有效字符后空白做结束符
- nextLine():以回车为结束符
选择结构
-
if(表达式){ ... }else if(表达式){ ... }else{ ... }
-
switch(比较变量){ case 变量值://变量值不可为非整数的实数 执行体; break; case 变量值: 执行体; break; ... default: //无匹配的变量值时执行该语句 执行体; }
循环结构
-
while(表达式){ //表达式为true时执行,先判断后执行 ... }
-
do{ ... }while(表达式); //表达式为true时执行,先执行后判断(至少执行一次),分号不可省略
-
for(变量初始化;表达式;变量更新){ ... }
-
//foreach 常用于遍历数组或集合 for(元素类型 x : 遍历对象 obj){ ... }
- 循环控制关键字
-
- break; //跳出当前循环,循环不再执行
- continue; //跳过某次循环,执行下次循环
面向对象
类——某类事物
- 大事务(一个类)—(面向对象)➡分为多个小事务(多个对象)—(面向过程)➡实现小事物
- 构造方法
- 无返回值,不需要 void 修饰
- 名称与本类相同
- 无构造方法声明时,默认有一个无参构造方法;有构造方法声明时,无默认构造方法
对象——某个具体的事物
- 实例化
- 使用 new 来调用构造方法,从而实例化为一个对象
- 每个对象在内存中占有独立的内存地址
- 引用
- 类名 引用名(引用名实际是一段内存地址,是对应内存地址的对象的标识)
封装(类内)
- 隐藏类的实现细节,包装数据,对外提供接口
- 实现高内聚(内部数据操作自己完成),低耦合(对外提供少量方法接口)
继承(类间)
- 特点
- 子类继承父类,是父类的扩展
- 单继承
- super(调用父类构造方法)即指向父类的对象,this(调用当前类构造方法)即指向当前类的对象,this和super不能同时调用构造方法
- 私有属性或方法无法被继承
- new子类对象时,先调用父类构造器,再调用子类构造器。
- 实现
- 子类 extends 父类
- 对象转型(必须具有继承关系)
- 向上转型
- 子类转父类:父类 名 = new 子类
- 安全的
- 无法调用子类的独有属性或方法
- 向下转型
- 父类转子类:子类 名 = (子类)父类
- 不安全的
- 由强制转换实现,且父类的引用指向子类的对象
- 向上转型
- instanceof
- 判断当前对象是否是某个类
- 使用
- 对象名 instanceof 类名
多态
- 同一事物多种形态(对象实际类型确定,引用类型不确定),要存在继承关系;
- 对象所能执行的方法主要看变量名左边的类型;
抽象类
- 被 abstract 修饰
- 不可被实例化
- 抽象类的抽象方法由子类实现,只能由继承实现抽象类
接口
- 被 interface 修饰
- 解决单继承问题
- 方法只能被 public 或 abstract 修饰
- 任意字段默认为 static 和 final 的
- 实现时要实现接口中的所有方法
内部类
- 成员内部类
- 可随意使用外部类的成员方法及成员变量
- 实例化
- 外部类.new 内部类
- 匿名内部类
- new 类名{
...
};
-
- 对抽象类实现实例化
- 不能写构造方法
- 不能定义静态成员
- {} 后跟 ; 结束
方法/函数——执行一个功能的语句的集合
函数结构
- 修饰符 返回值类型 方法名 ( 参数 ) throws Exception {
方法体
}
- 参数
- 实参:调用时传入参数
- 形参:建造方法时所需外部传递参数
- 可变参数
- 声明:参数类型 ... 参数名
- 规则:一个方法只能有一个,且必须做最后一个参数声明
参数传递方式
- 值传递:实际参数复制一份传递到函数中,函数中参数和实际参数互不干扰
- 引用传递:将实际参数的地址传入到函数中,函数中参数和实际参数为同一参数
重载与重写
- 重载
- 同一类中,方法名相同,参数列表不同(参数类型,个数,排列顺序等)
- 重写
- 子类重写父类方法(与属性无关),参数列表相同,执行体不同,访问权限不降
递归
- 递归头:表示什么时候结束递归
- 递归体:表示递归的具体执行方式
- 执行过程为栈结构
GC
垃圾识别
- 对象引用超过其作用范围
- 对象赋值为 null
垃圾回收
- 回收由 new 所创建的对象
- 当 Java 虚拟机内存耗尽时,不会执行垃圾回收
finalize 方法
- 在类中定义,属于 Object 类
- 第一次垃圾回收:调用该方法
- 第二次垃圾回收:回收被对象所占用的内存
异常
- try{
if(){
throw new exception //主动抛出异常 }
...
}catch(){ //捕获try中异常
}finally{
处理善后工作 } //无论是否出现异常finally内代码都一定会执行
- 自定义异常:继承exception类
实用类
包
- java.lang:包含基础类和接口,自动导入到所有程序中
- java.util:包含系统辅助类,如集合类,非默认导入
- java.io:包含输入/输出相关类
- java.net:包含网络相关类
- java.sql:包含数据库相关类
Math类
-
- abs(double a):返回绝对值
- max(double a , double b):返回最大值
- random():产生一个 0.0~1.0 之间的随机数
String类
- 方法
- length():返回字符串长度
- equals(String s):比较字符串,大小写敏感(==比较两字符串内存地址是否一致,equals比较两字符串内容是否一致)
- equalsIgnoreCase(String s):比较字符串,大小写不敏感
- concat(String s):s 拼接在字符串后面并返回新的字符串
- indexOf(int value/String value):返回第一个出现字符value的位置
- lastIndexOf(int value/String value):返回最后一个出现字符value的位置
- substring(int index)/substring(int beginindex , int endindex):提取指定部分的字符串
- trim():返回截取前后空格的字符串
- split(正则表达式 , limit):分割字符串,正则表达式描述分割规则,limit限制返回数组中的元素个数
- StringBuffer / StringBuilder
- toString():转化为String
- append( 参数 ):将任意类型参数连接到字符串后面
- insert(位置,参数):将任意类型参数插入到指定位置后面
- 对比
- String:是不可变对象,每次改变相当于生成了一个新的String对象
- StringBuffer:是可变对象,字符串连接时效率高,线程安全
- StringBuilder:单线程的,不提供同步
集合
Collections类(集合的操作类)
- 只有实现 Comparable 接口的类才可进行排序Collection
- 方法
- add(Object o)/add(int index , Object o):添加数据;
- set(int index , Object o):替换index处的数据为o;
- get(int index):获取数据,返回值为Object类型,使用前需要强转;
- remove(int index)/remove(Object o):删除元素;
- contains(Object o):判断o是否在表中;
- indexof(Object o):返回o所在表中的索引位置;
- size():返回表中元素个数;
- clear():清空表数据;
- isEmpty():判断表是否为空;
- iterate():返回一个Iterator类
List接口(可存储一组元素重复,有序的对象)
- ArrayList(动态数组):
- 对数组进行了封装,实现了长度可变的数组。
- 特点
- 可添加任何类型数据,并将添加的数据转换为Object类型。
- 遍历元素和随机访问效率高。
- LinkedList(链表)
- 特点
- 允许元素值是任何数据,包括null;
- 插入,删除效率高
- 方法
- addFirst(Object o):头插;
- addLast(Object o):尾插;
- getFirst():获取第一个元素;
- getLast():获取最后一个元素;
- removeFirst():删除第一个元素;
- removeLast():删除最后一个元素;
- 特点
Set接口(可存储一组元素不重复,无序的对象)
- HashSet
- 查找效率高
- 非线程安全的
- 允许元素值为null
Iterator接口(集合迭代器,实现集合的遍历)
- 方法
- hasNext():判断是否存在下一个可访问的元素
- next():返回要访问的下一个元素
- 遍历实现
while(iterator.hasNext()){
String value = (String)iterator.next();
System.out.println(value);
}
Map
- 方法
- put(Object key , Object value):放入键值对,若已包含了 key 对应的 value,则新值换旧值;
- remove(Object key):移除与指定 key 相关的映射,并返回 value 值,若无映射则返回 null;
- get(Object key):获取与指定 key 相关的映射,并返回 value 值,若无映射则返回 null;
- containsKey(Object key)/containsValue(Object value):判断是否存在 key/value;
- size():返回元素个数;
- clear():清空数据;
- isEmpty():判断是否为空;
- keySet():返回所有 key 的集合
- values():返回所有 value 的集合
Map接口
- 存储键值对,提供 key 到 value 的映射,通过 key 来检索
- key 不要求有序但不可重复,value 不要求有序但可重复
- HashMap
- 查询指定元素效率高
- 可添加任何类型数据,并将添加的数据转换为Object类型
枚举(Enum)
- 定义
修饰符 enum 名{
enumContantName1,enumContantName2... //枚举常量列表
}
泛型
- 本质:参数化类型(将对象的类型作为参数,指定到其他类或者方法上)
- 语法格式:类/接口<类型实参> 对象名 = new 类<类型实参>
- 优点:所有强制转换都是自动、隐式进行
- 参数化类型:包含一个类/接口,以及实际的类型参数列表
- 类型变量:非限定性标识符,用来指定类、接口、方法的类型
I/O
- File类(即可表示文件,也可表示目录)
- 方法
- File(String pathname)/File(String dir , String subpath)/File(File parent , String subpath):根据指定文件路径构造文件(dir指定路径,subpath指定文件名,parent指定目录文件)
- exists():文件是否存在
- getAbsolutePath():返回绝对路径
- getName():返回文件名
- getParent():返回上级文件名
- delete():删除(若为目录,则目录空时才可删除)
- creaeteNewFile():创建空文件
- isDirectory():文件是否为目录
- 方法
- 流
- 一串流动的字符,是以先进先出的方式发送和接收数据的通道
- 输入流(输入到内存)
- 方法
- read():读取下一个字节/字符数据并返回
- read(byte[] b):读取数据保存到 b 中,并返回读取的字节/字符数
- read(byte[] b , int off , int len):读取最大 len 长度的字节/字符,保存到 b 中,保存位置从 off 开始
- InputStream(面向字节)
- FileInputStream:将文件中的数据输入到内存中
- DataInputStream:将二进制文件数据输入到内存中
- Reader(面向字符)
FileReader fr = new FileReader("文件绝对路径"); BufferedReader br = new BufferedReader(fr); String line = br.readLine() //读取一行数据 while(line != null){ System.out.println(Line); line = br.readLine(); }
- System.in(标准输入流):从键盘接收数据
- 方法
- 输出流(从内存输出)
- 方法
- write(int c)/write(String c):将指定字节数据/字符串里的字符数据写入输出流
- write(byte[] buf):将 buf 中所有数据写入输出流
- write(byte[] b , int off , int len)/write(String b , int off , int len):将从数组/字符串 off 位置开始,长度为 len 的数据写入输出流
- outputStream(面向字节)
- FileOutputStream:将内存中的数据输入到文件中(文件不存在则自动创建,文件为目录则抛出异常)
- DataOutputStream:将内存中数据输入到二进制文件
- Writer(面向字符)
FileWriter fw = new FileWriter("文件结对路径"); BufferedWriter bw = new BufferedWriter(fw); ...; bw.flush; //刷新缓冲区
- System.out(标准输出流):向屏幕输出数据
- 方法
- 标准I/O重定向(实现指定文件/设备完成输入/输出)
- setErr(PrintSteam err):重定向标准错误输出流
- setOut(PrintSteam out):重定向标准输出流
- setIn(InputStrea in):重定向标准输入流
- 序列化
- 将对象的状态存储到特定存储介质中的过程
- 过程
- 公有成员/私有成员/类名➡字节流➡写入数据流➡存储到存储介质
- 特点
- 将Java对象转换为字节序列(借助I/O流实现)
- 序列化后对象为二进制状态,从而实现跨平台
- 只有实现了 Serializable 接口的类才可序列化(Serializable表示可串行的,可序列化的)
- 可用 transient 来修饰某个属性是否可序列化
- 所有保存到磁盘中的对象都有一个序列号
- 实现
//创建对象输出流 ObjectOutputStream oos = new ObjectOutputStream(new 其他类型输出流); //对象序列化,写入输出流 oos.writeObject(对象);
- 反序列化
- 从特定存储介质中读取数据并重构成对象的过程
- 特点
- 序列化机制写入多个对象时,则反序列化时必须按照写入顺序读取
- 实现
//创建对象输入流 ObjectInputStream ois = new ObjectInputStream(new 其他类型输出流); //反序列化,并进行强制类型转换 (对象类型)ois.readObject(对象);
- 反射
- 在运行状态中,动态获取信息及动态调用对象的功能
- 功能
- 运行时判断任意对象所属的类
- 运行时构造任意一个类的对象
- 运行时判断任意一个类所具有的方法和属性
- 运行时调用任意一个对象的方法
- 类
- Class类:可获取类的属性、方法等内容信息
- Field类:可获取/设置类中属性的值
- Method类:可获取/执行类中的方法
- 应用
- 获取某个类的Class对象
- 调用 getClass() 方法
- 调用 class 属性
- 调用 Class 类的 forName(“某个类的路径全名”) 方法
- 从Class对象获取信息
- 获取对应类的构造方法
- 获取对应类的方法
- 获取对应类的属性
- ...
- 创建对象
- 使用 Class 对象的 newInstance() (使用默认构造方法)
- 使用 Constructor 对象的 newInstance() (可指定构造方法)
- 访问类的方法
- invoke(Object obj , Object args) (obj 是执行该方法的对象,args 是传入的参数)
- 获取某个类的Class对象
注解
- 语法:@Annotation( 参数 ) //Annotation为注解类型,参数可以没有也可以有多个
- 特点
- 不影响代码编译执行
- 用来生成其他的文件或使我们在程序运行代码时知道被运行代码的描述信息
- 可修饰任何程序元素
- 使用
- 置于所有修饰符之前
- 单独一行
- 内建注解
- @Override
- 用来标注方法,表示该方法时重写父类的某方法
- @Deprecated
- 标识程序元素已过时
- @SuppressWarnings
- 标识被禁止的编译器警告,实现有选择地关闭编译器对类、方法和成员变量等元素及其子元素的警告
- 注释参数
- deprecation:使用了过时程序元素
- unchecked:执行了未检查的转换
- unused:未被使用
- fallthrough:switch 没有 break
- path:在路径中有不存在路径
- serial:可序列化的类上缺少定义
- finally:finally子句不能正常完成
- all:所有情况
- @Override
- 元注解(修饰其他注释)
- @Target
- 指定被修饰的注解能用于修饰哪些程序元素
- 参数(位于ElementType枚举类型中)
- ANNOTATION_TYPE:注释
- CONSTRUCTOR:构造方法
- FIELD:成员变量
- LOCAL_VARIABLE:局部变量
- METHOD:方法
- PACKAGE:包
- PARAMETER:参数
- TYPE:类、接口、枚举
- @Retention
- 描述了被修饰注解是否被编译器丢弃或者保留在 class 文件中(默认保存)
- 参数(位于RetentionPolicy枚举类型中)
- CLASS:编译时保存在 class 文件中,运行时丢弃,程序不可通过反射对注释进行访问(默认值)
- RUNTIME:编译时保存在 class 文件中,运行时保留,程序可通过反射对注释进行访问
- SOURCE:直接丢弃注解
- @Documented
- 被修饰的注解将被 JavaDoc 工具提取成文档
- @Inherited
- 被修饰的注解具有继承性
- @Target
- 自定义注解
- public @interface 注解名{}
多线程
- 主线程:main() 方法是主线程的入口
- 方法
- run():执行操作
- start():开始执行
- stop():终止线程
- interrupt():中断
- setPriority(int grade):设置线程优先级
- 线程阻塞
- yield()
- 暂停调用该方法的线程并执行其他线程
- 使调用该方法的线程不进入阻塞态,为就绪态
- join()
- 暂停当前线程,使调用该方法的线程执行(抢占 cpu )
- 阻塞当前系统执行的线程
- sleep(long millis)
- 使调用该方法的线程休眠(毫秒)
- 使调用该方法的线程进入阻塞态
- yield()
- 线程通信
- wait()
- 挂起调用该方法的线程,并释放共享资源的锁
- notify():唤醒因调用 wait() 方法而挂起的任意一个线程
- botifyAll():唤醒因调用 wait() 方法而挂起的全部线程
- wait()
- 创建
//Thread类实现
public class MyThread extends Thread{ //继承Thread类
public void run(){ //重写run方法,实现所要执行的任务
执行体
}
}
//Runnable接口实现
public class MyThread implements Runnable{ //继承Thread类
public void run(){ //实现run方法,实现所要执行的任务
执行体
}
}
- 调度
- 优先级调度算法
- 优先级:1~10,默认为5,值越大优先级越高
- 线程同步
- synchronized 关键字
- 实现锁机制
- 同步方法实现
- 语法:访问修饰符 synchronized 返回类型 方法名{ ... } / synchronized 访问修饰符 返回类型 方法名{ ... }
- synchronized 关键字修饰的方法控制对类成员变量的访问,每个类实例对应一把锁
- 同步代码块
- 语法:synchronized(syncObject){ //需要同步访问控制的代码 } // syncObject 即为临界资源
- 代码块中代码只有获取对象 syncObject 的锁才能执行
- synchronized 关键字
- 避免死锁
- 受阻时不让其继续占有资源
- 提前确定线程执行顺序
网络编程
- 网络:连接在一起共享数据和资源的一组计算机
- InetAddress 类
- 用于封装IP地址和DNS
- 无可用构造方法,声明实例用工厂方法
- 工厂方法
- getLocalHost():返回本地主机的 InetAddress 对象
- getByName(String hostName):返回指定主机名为 hostName 的 InetAddress 对象
- getAllByName(String hostName):返回指定主机名为 hostName 的所有可能 InetAddress 对象
- 基于 TCP 的 Socket(先建立连接再发送数据)
- 方法
- getPort():获得所连接的远程端口
- getLocalPort():获得本地端口
- getInputStream():获得关联的输入流
- getOutputStream():获得关联的输出流
- close():关闭
- accept():等待客户端发起通信
- Socket 类
- 实现双向安全连接的客户端
- 声明
- Socket s = new Socket( hostName , port ) // hostName 为主机名,post 为端口号
- Socket s = new Socket( address , port ) // address为 InetAddress 对象,post 为端口号
- ServerSocket
- 实现双向安全连接的服务器端
- 声明
- ServerSocket ss = new ServerSocket( port ) // post 为接收端口号
- ServerSocket ss = new ServerSocket( port , maxqu) // maxqu 表示系统可拥有的最大客户端连接数
- 方法
- 基于 UDP 的 Socket(不建立链接直接发送数据)
- 两端关系是对等的
- DatagramPacket 类
- 类似于数据报
- 声明
- DatagramPacket( byte[] data , int size ) //构造对象并封装长度为 size 的数据包
- DatagramPacket( byte[] buf , int length , InetAddress address , int port) //构造对象,封装长度为 length 的数据包并发送到指定主机、端口号
- 方法
- getData()
- getLength()
- getAddress()
- getPort()
- DatagramSocket 类
- 发送/接收 DatagramPacket
- 声明
- DatagramSocket() //创建对象并与本地主机上任何可用端口绑定
- DatagramSocket( int port) //创建对象并与指定端口绑定
- 方法
- connect( InetAddress address , int port):连接到远程地址的指定端口
- disconnect()
- close()
- getLocalPort():获得当前绑定的本地端口号
- send( DatagramPacket ):发送数据包
- receive( DatagramPacket ):接收数据包
Java内存
- 堆
-
- 存放new的对象,每个对象有一个各自的内存地址
- 栈
-
- 存放当前程序的方法和引用变量等内容
- 每个引用变量指向堆中的一个对象
- 方法区
-
- 加载的类存放在方法区中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现