java notes
java Development toolKit java开发工具包
javase standard edition 标准版
javaee enterprise edition 企业版
javame mobile edition
big bro. Sybian 塞班 NOKIA
little bros. IOS Android
8.0 ? java fundation
SUN 升阳公司 java.lang java.util java.math ....
javax.xxxx extensible 可拓展的
unix 系统一体化 解决方案
HP 惠普 windows heavey 重
IBM 晶体管的不断缩小 2nm 5nm
windows Linux unix macos ubuntu chromeOS
ORACLE 甲骨文
oceanDB GoldenDB (关系型数据库)
redis magodb ...
9 10 12 17 19
openJDK8 11 不能在 Oracle 官网下载 需要在 阿里 或者其他可信的开源网站下载
Eclipse
.java 源文件
java Development toolKit java开发工具包
javase standard edition 标准版
javaee enterprise edition 企业版
javame mobile edition
big bro. Sybian 塞班 NOKIA
little bros. IOS Android
8.0 ? java fundation
SUN 升阳公司 java.lang java.util java.math ....
javax.xxxx extensible 可拓展的
unix 系统一体化 解决方案
HP 惠普 windows heavey 重
IBM 晶体管的不断缩小 2nm 5nm
windows Linux unix macos ubuntu chromeOS
ORACLE 甲骨文
oceanDB GoldenDB (关系型数据库)
redis magodb ...
9 10 12 17 19
openJDK8 11 不能在 Oracle 官网下载 需要在 阿里 或者其他可信的开源网站下载
Eclipse
.java 源文件
把源文件 变成 java 可以理解的内容的 命令 叫做 javac - java compile
生成 一个 .class 文件(这是一个 二进制的字节码 文件)
谁来理解 这个 .class
跨平台性特别的好!!!!!
windows server intel x86 架构 开发者型
macos m1 m2 ARM架构 处女座(广告 绘图 制图)
unix intel 专业企业级 (不会单独存在 ,都是和服务器进行一体化解决)
Linux intel 高级玩家型
指令集 不一样,处理器的架构可能都不一样
java 为每一个平台 都准备了相应的 “翻译机”- javac compile
安装 java 的时候就要选择 对应操作系统的 java
在每一个 操作系统中 生成 一个 环境-environment
eg: 我想要 打印- > windows :
1. 用java 表达出 我要 打印这个动作 的代码 .java
2. java的windows翻译机 会翻译这个 代码 变成 window能够理解的指令集 .class
3. java 启动 jvm - java virtual machine java虚拟电脑 产生一个 jre java runtime environment
4. 把刚才翻译好的windows 指令集 给虚拟电脑
5. 虚拟电脑链接 windows 实体电脑 链接的打印机接口 进行打印
如何 写好一个 java
1. java文件名 要和 类名完全一致
2. 首字母大写,多个单词连在一起的时候,每个单词 首字母也要大写 eg: MyWorldBeauty
访问修饰符号 类的声明符号 类名 {
public class MyWorldBeauty {
}
package 包 一般写在 类文件的 最上面!!! (3个功能)
1. 包其实就是一种文件夹
常用 快捷
alt + / 补全
ctrl + z 撤销
ctrl + a 全选
ctrl + c 复制
ctrl + v 粘贴
ctrl + shift + f 代码整理
ctrl + d 删除一行
ctrl + s 保存
// 注释
// 单行注释
/*
多行注释
*/
/**
* 文档注释
*/
warning: 注释 不会出现在 .class 文件中 所以 你不用担心注释过多的问题。
javac 翻译成 jvm java virtual machine能够理解的内容
java 输入核心业务支撑的语言之一
java 属于 强类型 (清楚的定义每一种类型)
/*
* 原生 数据类型 小写 红色 关键字
* int 整型 = 0
* short 短整型 = 0
* long 长整型 = 0
*
* float 单精度浮点型 = 0.0
* double 双精度浮点 = 0.0
*
* char 字符型 = ''
* byte 字节型 = 0
*
* boolean 布尔型 = false
*
*
*
*/
jvm 小电脑启动起来 他也要有一块属于自己的内存,划分一下自己的小领地
分成了 如下部分
堆 heap 多 杂(会导致性能下降) 是 java 虚拟机中 真正意义上存放 实际内容的区域,你可以理解成虚拟世界,有创造也有销毁。
栈 stack 中 存放的是 指向 堆中某个房间(对象)的钥匙,而且 栈中的钥匙(内容)都是有顺序的
常量池 constant pool
寄存器 memory
静态区 static area
常量 constant 是一旦定义就不能修改的内容 ,jvm 会为每一种原生类型维护在常量池中维护一套。同一个类型的相同数据 只会有一个。所以 用不到的常量 不用写,内存溢出。
java环境的 2 种状态
1. 编译期 compiler
2. 运行时 runtime
逻辑判断最基本的就是 if else
if 和 else 只会运行一个
if else 可以相互嵌套
* 有 if 可以没有 else 吗? 可以
* else 可以单独存在吗? 不可以
Java 中的循环体
循环的嵌套 不应该超过 2层
java keywords 关键字
int double short float byte long boolean char
public class main void
true false
if else
1. 如何定义一个变量(局部变量)
数据类型 变量名 = 值(可选);
int i = 10;
它必须存在于 方法中!!
2. 原生数据类型的特殊定义
boolean bool = true;
char ch = 'A';
char ch1 = 64;
3. 数字的组成
1字节 = 8bit
0000 0000 = 0
0000 0001 = 1
0000 0010 = 2
0000 1000 = 8
二进制 binary
八进制 orctal
十六进制 Hex
for 循環
需要帶 3個 條件 (非必须)
for(起始变量 ; 循环条件; 增长因子){}
&&
||
!
key words
return 结束当前函数逻辑
break 终止循环 不影响循环外部的逻辑执行
continue 继续(立刻结束本次循环 但继续下一轮循环)
while(expression){}
do{}while(expression)
dowhile 至少比 while 多执行一次逻辑
if(i== 10)
else if()
else if()
else
if else 更偏向于 逻辑方向的控制
我们很少用它来 比对数值 等情况
switch(原生数据类型)(注意 在 jdk5.0 后 可以放 String)
常量 constant
我们希望定义一些 模板类型的 量 只能用 不能修改
除了 数值的常量之外。变量不能修改指向的时候 也是一种常量
final 最终 最后一次
被 final 修饰的 变量 它不能被修改引用
OOP Object Oriented Programming 面向对象编程
C 一直没有 推动 大面积的 移动化的 软件开发
POP Prograss Oriented Programming 面向过程编程
结构体
设计模式 (错误)
设计思想 (正确)
POP -》 OOP -》 AOP
case1. 老王开车到东北
优点: 快速 简单 直接 执行不需要 思考
缺点: 毫无重用性可言,而且反人类的思想
面向对象
把所有 肉眼可见的东西,或者想象的东西转换成 计算机世界的 内容。
什么是对象? 是具有相同特征群体中的具体的个例 (类的实例)
什么类? 是对具有相同特征对象的抽象(是对象的抽象)
类只能停留在书面上且永垂不朽
对象活在实际之中面临生死考验(创建和销毁)
类的 定义
访问权限修饰符 类修饰符 类名 { }
public class Person{ }
* 一个 类文件中 只应该有一个类
* 类名一定要有意义 且一定是一个名词
* 类名不能以数字开头 可以 $ _ 等符号开头
* 多个单词必须使用驼峰命名法则
类中 有什么?
1. 包 的概念。 包(package)本身就是文件夹, 包也是写在类最上方的内容
a. 解决类命名冲突的问题
java 本身有很多常用的包
java.lang (浪) 存放了 java 很多重要的系统对象和核心支撑对象 需要注意: 使用这个包中的所有类都不需要导包(import)!!!!
java.util -> utility 通用的 Random Scanner (用的时候 需要导入)
java.math
java.io
java.nio
b. 业务的分层
可以通过包的不同 把项目分成很多的业务模块,有助于团队的协作开发
c. 访问权限的控制
类被实例化成对象之后,涉及到对象之间的访问的时候,就会需要访问权限。那包就促成了 访问权限的控制。
JAVA中四种访问的权限 public protected 默认的 private
JAVA中四种访问需求 同一个类 同一个包 不同包的子类 不同包的非子类
同一个类 同一个包 不同包的子类 不同包的非子类
public 可 可
protected 可 可
默认的 可 可
private 可 不可
2. 全局变量
定义在类里面的量 -》 全局变量,类中所有的内容都可以访问,类中所有的逻辑都可以操作(通存通取)这个变量
3. 全局常量
被final 修饰过的 全局变量
4. 函数 方法 功能
修饰符 返回类型 方法名称( 参数, .......){ }
方法名需要一个动词
方法执行后 没有结果的时候 ,返回类型使用 void。反之 如果你想要给一个 运行结果 则 填写实际的返回类型
关键字 new 创建 对象
任何的类 都没有办法直接进行使用,必须通过 new 关键字进行实例化
我们说 对象 是 类的 实例。
请注意: 未来 无论 你看见 或者 看不见 new 这个关键字,只要是对象,就一定new过
大部分的 类 都可以new
对象 存在于 内存中,它被创造 也会在不使用的时候被销毁
方法的调用
外部调用的时候 我们需要用 对象名.方法名()
内部调用的时候 我们可以使用 this.方法名( )
关键字 this 这这个
在类中撰写 this 表示 当前运行的这个对象
构造方法 construct
创建 对象其实是调用 类中的 构造方法进行创建的
* 如果我们的类中没有任何的构造方法的时候。java 默认使用一个不带参数的空构造
* 如果类中有任意的构造方法,则java不会产生默认的不带参数的空构造
* 遵循了 构造方法重载的要求之后。在同一个类中 不同的构造方法之间 使用 this() 来进行调用
方法的重载
有的时候 我们希望 同样的方法能够提供更多的参数 来让我们选择 合适的进行调用
方法的重载 要求 方法名一样,返回类型可以一样可以不一样,参数的个数位置 类型不能都一样。
* 通过方法的重载,我们创建的方法越多,调用者所要做的就越少
构造方法的重载
我们允许在类中有多个构造方法 用来帮助我们更好的实例化对象
但是我们要遵循以下要求
1. 构造方法名一致
2. 构造方法参数的 个数 位置 类型 不能都一样
String
数组
static serial 静态变量 静态方法
final 修饰方法 修饰类
面向对象 三大 特征
1. 封装 encapsulation
2.继承 inheritance
abstract
implement
Enumeration
3.多态性 polymophsim
包装类 (装箱 和 拆箱)
日期类 时间类
util 的一些常用工具
对象 是根据 类 new(实例化)得来的
对象被放入 heap 中,并且通过栈中的 地址进行查找。我们看不见地址 但是 我们有一个 hashcode(哈希码) 来证明它的唯一。
String 字符串 // byte short int long float double boolean char
char = 97 // 0- 65535
char = 'A'
String 字符串
数 组
java 中数组的一些要求
1. 数组的定义 数组必须给定初始数据或者长度数据
int[] group = {1, 23,1,12 };
int[] group = new int[12] ;
2. 数组的 成员只能是 数组定义时规定的类型
3. 数组可以定义成任何的类型
4. 数组一旦定义长度 就不能放大 也不能缩小
5. 数组的下标 从 0 开始
数组的排序
1. 为什么要排序?
高效率的动作 都需要数组的有序
2. 排序的方式?
冒泡 二分查找 红黑树 。。。。
数组的复制
推荐 使用 System.arrayCopy()
多维数组 Mutil-group
java的世界中没有 多维数组 ,只有数组套数
在一维数组中嵌套一个 一维数组 ,以此类推
但是在构建的时候 最外层的一维数组 一定要赋予初始值
数组操作的工具类 Arrays
static
* 处理器最耗时的工作 之一 就是创建对象,耗内存
后来我们经常把逻辑简单,不需要个性化定制的内容 封装成工具 并定义为 静态的内容 ,让大家反复使用
static 定义的内容通常主体是不能销毁。
static 不需要实例化 就可以使用。 调用方式为 [ 类名.静态方法() ] [ 类名.属性 ]
static 只能用来 修饰 方法 和 成员变量(全局变量)
* static 不需要对象 也会存在于 内存的 静态区域中
* 一旦定义就不能销毁,只有等 jvm 关闭
* static 只加载 一次!!!
* 经典的 main 方法 到底是 什么操作?
静态内容的访问范围?
由于 static的内容是不属于对象的,且会优先的加载入内存
所以对于所有的对象来说,静态的内容是共享的!
JVM garbage collection 垃圾回收机制
String
其实就是 字符类型的数组
在 String 体内 用 char 数组来存储数据,并且用private 和 final 对其进行了修饰。说明 它 不能被访问,也不能被修改指向。
String 一旦定义就不能被修改!!!!!
*** 只有在学术中 探讨 String 的时候我们使用 == 进行判断,在实际工作中绝不允许 使用 == 进行 String 的判断!!!!!
final
Enumeration
Review
数组
1. 数组是对象,使用前应该初始化
a. int[] group = { .... };
b. int[] group = new int[x];
2. 数组是定长的,一旦定义就不能修改,只能重新再建立
3. 数组只有一个 length 属性,用于反馈数组的长度,但不能知道数组中成员的实际个数
4. 数组删除成员并不能缩小数组的尺寸
String
一个 用来存储一系列字符串的对象。一个非常像原生数据类型的对象
String s = "abc";
String s = new String("xxx");
String 切不可使用 == 进行比较!!
String 一旦定义就不能修改!!
为了保护 String 的安全,JAVA 做了什么?
a. final 关键字 修饰 String让 任何人不可以对其进行继承性的拓展!
b. 再构建之后 立刻用 final private 来修饰存储字符的数组,保证了在构造之后 外部不能访问,内部不能修改!
由于特殊性,我们始终不建议使用
String s = new String("") ; 空的建立!
API java 指导手册(类的查询工具)
Arrays 数字工具的查询
String 的查询
String 的常用方法
charAt
endsWith
startsWith
contains
concat
contentEquals
equals // 字符穿的比较关键
compareTo
indexOf 找不到返回 -1 所有内容从头开始 找到即停止!
lastIndexOf
split
subString // 包前不包后
原生 和 与之相对应的更为强大的 包装类型
原生 byte short int long double float boolean char
包装形态 Byte Short Integer Long Doubler Float Boolean Character String
在后续的学习过程中,除非在方法的逻辑执行过程中我们使用 原生数据类型进行数据的存和取,大部分其余的定义动作都应该使用包装类型!!!
字符集的问题?
utf-8 union text format max 8 世界所有的文字
每个中文字在 utf-8 的字符集中 3- 6个不等的字符
GBK 中文简体和繁体统一
GB2312 简体
永远记住第一件事情就是统一字符 使用 utf-8
Poker Game
1. 数组
2. 字符串
3. 对象
String + 数组 + 对象 + 逻辑操作
charAt
indexOf
lastIndexOf
trim
subString
spilit
getBytes
compareTo
equals
valueOf
自己定义方法名称的时候 一定要有 意义!!!
OOP 面向对象 Object Oriented Programming
对象: 类的实例,是具有 相同特征抽象体的具体实现(某一个具体),对象特指真实存在的个体。
类:对象的抽象
只有面向对象,把一切看作是对象。
元宇宙的重要支撑
JRE java runtime environment -> JVM java virtual machine
面向对象的 三大 特征
1.封装 encapsulation
保护好对象中的成员才是封装最大的任务!
禁止 外部对成员的 直接方法 和修改!
开放合理的访问和修改
私有化成员变量 并按需 为成员变量开启访问和操作
开启可控的读写权限 需要 get 和 set 的支持
getter setter 的撰写是有规则的!!!!
get + 成员变量名(首字母大写)
原生数据类型是无法映射(reflect)偏偏 映射 是java 高级别开发的必备!!!
2.继承 enheritant
java 中的 继承更多的是 拓展,是在 父类 不能够满足 现有运行条件的基础上进行继承和拓展的
继承 既能够保证原有的程序 不被修改的情况下 又能够 进行 新程序的开发,按需使用按需调用。
为什么要使用继承? 程序的开发有一个原则 - 对修改关闭 对拓展开发
如何进行继承操作? extends
java 的世界中 没有任何对象 是凭空出来的,他是对象 他被称为对象的时候 他就已经继承了对象
java 中只能单继承!!!!!!
实例化(new)一个有继承的类的时候 会先实例化它的父类再实例化子类(自己), 实例化的对象 可以用一个 父类变量来接收 也可以用子类变量来接收
Object
万物 都是 Object 的孩子 (万物皆继承于 Object)
所有的对象都是 Object 的子类
访问权限的补全
同一个类 同一个包 不同包的子类 不同包的非子类
public 可 可 可 可
protected 可 可 可 不可
默认的 可 可 不可 不可
private 可 不可 不可 不可
继承的注意事项
1. 所有的类都能继承,但是只能是单继承。 如果你想要继承更多的对象,需要 通过其他类进行完成
A -> B -> C A -> C
2. 继承后 需要注意访问权限,否则有些内容即便是继承了 也不能访问
3. 使用 extends 关键字进行继承
4. 不能相互继承 A->B 同时 B -> A 是不可以的!
java的两种状态
1. 编译期 complile time
2. 运行时 run time
继承的目的
是应为 父类有一些功能不能够满足新的业务,加上对修改关闭 对拓展开发的约束,我们只能
通过 子类进行 拓展。
继承的调用需要注意点:
1. 子类可以访问父类可以被的访问的方法或者属性
2. 如果子类没有这个方法 则会调用父类的方法,如果父类没有 则会调用 更上一层的类,直到找到位置。
3. 子类有的方法 先调用子类 子类没有才会调用父类
方法的拓展(重写)
1. 重写必须在父子类中发生
2. 子类重写父类的方法
3. 方法名必须完全的一致
4. 返回值 可以一致 可以不一致
4. 方法参数的 个数 位置 类型 都不能完全的一致
抽象类
接口
enumeration
3.多态性 polimophsim
方法中的变量 叫 局部变量
类中变量 叫 全局变量
局部变量 在方法执行完毕之后 就会 销毁 但是 已经生成的对象 如果还有被外部 引用的 则不会销毁。等 JVM 检查
内存的时候 发现这些对象 已经 没人去使用的时候就会回收他 我们不用操心
static 可以修饰 全局变量
static 可以修饰 方法
static 可以写一个 静态块
static 的内容 是先于类中所有的内容
static 不属于对象 所以 无论 类实例化多少次 和静态 毫无关系
static 内容的调用 是 类名.staticFunctions or 类名.staticParameters
java 世界中的每一个对象 都应该是 个性鲜明的
对象(非静态)访问静态 内容 如何使用?
静态的 访问非静态的? 先new对象 再调用
Object 中的 一些重要的方法
Object 是所有类的根,无论是 是否 显式的继承过Object,你都会 继承它,可能是你的父类,祖父类等等
clone 克隆
一个从底层直接完整的复制一个对象的功能。复制出的对象和原生对象完全一样, 包括 父类 和其他的关联
分为 深 和 浅 的克隆 。
目前 对于 复杂的对象来说 ,克隆还不可靠!
而且 克隆 需要 类 实现接口 CLonable
equals()
新建的2个对象之间的比较 永远是不等的!!!!
==
hashCode() native
哈希码 - 哈希码 是 计算机上的一种 计算规则,用来将对象通过固定的算法 转换成一个唯一的数字串。
它能够尽最大可能保证 计算机内存中的每一个对象都有一个唯一的数字串
所以 我们认为 hashcode 不一样的2个对象 他们就是不一样的对象!!!!
finalize()
当垃圾回收 检查这个对象时发现 不再有 变量引用这个 对象的时候,垃圾回收机制将调用这个方法后准备回收
final finally 后续都会说
getClass()
获取对象的 类的抽象的形式(类的模型)
toString() // 变成String
关键字 native 是 底层 和 C 语言 的虚拟机进行交互的方法,这个方法 由 虚拟机来实现和完成
关键字 instanceof instance(实例化) of 是不是这个实例化
关键字 super
子类用英语怎么说? subclass
父类 super class
super()
一个 写在 构造器中的 调用方法 用来调用 父类的构造器。 需要注意的是: super() 只可以写在 构造方法的第一行!!!!!(父类必须优先被实例化)
super.xxx()
可以调用父类的方法。写在 方法的任意位置上
super.成员变量
如果 父类和子类都有相同名字的成员变量的时候 已实际调用的变量的类型为准
重写的要求
1. 重写必须 发生于 父子类之间
2. 子类重写父类的方法
3. 方法名必须一样 返回值可以一样 可以不一样,参数的个数 位置 类型 不能完全一样
抽象类 abstract
如果方法能够 不用撰写具体的内容,而是根据不同的需求 来进行拓展就好了
使用 abstract 关键字 修饰类,让类变成抽象类
抽象类的责任是 只定义不实现!!!!
抽象类 由于包含了 不确定逻辑的方法(抽象方法),所以抽象类 不能被实例化(new)
就可以撰写 抽象方法了,抽象方法 必须存放在抽象类中
抽象类 有什么好处
1. 定义速度快
2. 可以不用考虑实现的内容
抽象类 不能直接运行,所以抽象类需要用 子类来进行继承。
继承的子类必须实现抽象类中所有未实现的方法 一个都不能少!!!!
抽象类 比普通好在哪儿?
1. 抽象类 只需要定义,不需要实现。 普通类 还需要 实现每一个方法
2. 在继承方面。我们都知道 继承目的是 拓展。但是 如果继承一个普通类 我们可以不拓展。但是抽象类具备拓展的强制性
子类必须实现 抽象类中所有的抽象方法。
当你希望 有一些方法一定要求子类进行重写的话,你可以定义成 抽象的。
抽象类中 既可以有抽象类 也可以有 普通方法
如果 你觉 父类 写的好 你可以直接用 如果你觉得 父类写的不好 你可以选择重写
接口 interface
抽象类 毕竟还是一个类 还需要 使用 extends 进行继承 同样需要遵守继承的所有规则
枚举
多态性
byte 0
short 0
int 0
long 0
float 0.0f
double 0.0
boolean false
char ''
String null
Object null
char 的初始值是 Empty 空 (有缸没有水)
Object 的初始值 null 空 (连缸都没有)
StringBuilder
StringBuffer
虽然 字符串相加是可行的,但是在常量变量混合的累加过程中
效率是非常低下的,而且容易造成内存溢出。虽然1.8 在持续
改进String 的拼接效率和性能,但是我们始终还是建议大家使用
StringBuilder 和 StringBuffer
StringBuilder 线程不安全的 字符串拼接对象
StringBuffer 线程安全型的字符串拼接对象
如果在方法里面用,可以使用stringbuilder
如果在类(全局)中使用,推荐使用StringBuffer
A B
戴龙森 + 龚志坚
char 数组 把 数组里的每一个字符 依次累加 进入 sb
【戴 龙 森 龚 志 坚】 = 戴龙森龚志坚
【戴 龙 龚 志 森 坚】 把 sb 放在全局下 可能发生的极端情况
如果 你要 全局使用 你可以选择 stringbuffer
synchronized 同步锁
【戴 龙 森 龚 志 坚 】但是 由效率的问题但是绝对的安全 绝对的同步
******重要!!!!
在方法 里面 所有的局部变量 都是属于线程(调用者自己的)的!!!!!!
数字生成器,功能:把数字装转换成指定位数的字符串 例如 数字1 变成 6位 000001
包装类 装箱 和 拆箱
int Integer
short Short
byte Byte
char Character
long Long
double Double
float Float
boolean Boolean
装箱: 把原生数据类型 送给 包装类 系统会调用 包装类的静态方法
拆箱: 把包装类型 转换成 原生类型 系统调用包装类 xxValue() 方法
关键字
byte int short long double float boolean char
public protected private
for while do switch case default
if else break continue
static void return
final class package abstract interface static
try catch finally
native synchronized import
extends implements
this super transient goto volatile
Date SimpleDateFormat
Calendar
LocalTime
LocalDate
DateFormatter
Review 装箱和拆箱
BigDecimal
1. 日历 日期
Date
SimpleDateFormat
Calendar & TimeZone
GMT+8 China
GMT- 8 夏威夷 美国
GMT +8 Japan
GMT 英国
全新的 日期類
LocalDate
LocalTime
LocalDateTime
u nian
M 月
d 日
日期的格式 SimpleDateFormat DateTimeFormatter 区别?
最大的区别就是 DateTimeFormatter 是线程安全的
而 SimpleDateFormat 是线程不安全的
TimeZone
2. 值传递 引用传递
引用传递通常传递对象
对象传递的是 hashcode(引用/地址),我们通过 hashcode 找到对象并修改这个对象之后
所有引用这个对象的 变量都会收到影响
作业
1. 学生信息录入系统的 查询删除功能
2. 学号排序功能
3. 保存功能的接口预留
4. 时区转换的小系统,通过 指定时区 来进行时间的转换
3. Math
4. JVM 中的垃圾回收的 浅谈
5. instanceof 辨别 对象
1. finally
当程序出现异常 进行回滚的时候,异常之后, try里面的(不包含 try 外面的)代码 都不会再执行,所以 我们可以使用 finally
来进行一些收尾工作。譬如:关闭文件。关闭流等等
有 try 一定有 catch吗? 不一定
反之 有 catch 一定有 try 吗? 是的
try 可以嵌套 try 吗? 可以
catch 可以嵌套 try 吗? 可以
finally 可以 独立存在吗? 不可以
class A extends B{
A(String a){
super(“a”)
}
A(int a){
this(“a”)
}
集合
集合的 根接口 叫做 Iterable 所有 能夠被 foreach 的目標對象 都是他的子实现
元素:Elememt 表示 集合中的成员
Iterable 反推出 内在的结构 可能类似于数组
Collection 集合接口 表示 一系列 被称为 元素的子成员 组成的 对象, 这个集合中 有的 可以有序 有的 可能无序, 有的 可以重复 有的 不能重复
List 列表 有序的集合, 用户可以精准的存取成员(元素) 后进先出 LIFO last in first out
ArrayList 通常用来存放 类型相同的 一系列连贯成员的工具
1. 有序的集合 // 大部分的时候 我们的数据在获取 和处理之后 已经有了一定的顺序,使用 ArrayList 的目的仅仅是为了存放,所以 不能搞错了原有的顺序。
2. 可以重复
3. 可以为null
4. 线程不安全 // 说明 ArrayList 不能放在全局 称为 成员变量
LinkedList 和 ArrayList 一样用来存储 相同类型的成员
但是 LinkedList 可以用更加丰富的方法 来操作我们的 列表 Queue(队列) Dequeue(双端队列)
由于 实现过这两个 接口 所以 LinkedList 是 先进先出 FIFO first in first out
1. 有序的集合
2. 可以重复
3. 可以为null
4. 线程不安全
for each for(Object every : list)
遍历: 只要 符合 Iterable 的接口要求 都可以进行 for each 操作。
但是 for each 操作不是没有缺点的,必须要获得 完整的集合对象。
集合框架中的 迭代器 Iterator
迭代器 遮蔽了 制作 保存 过程中的所有信息和对象 只提供 迭代器接口
调用者 只需要 专注于 数据的处理就可以了 不需要知道 其他的信息
<> 我们称其为泛型 E 元素类型(成员类型) T 类型(Type) PK 主键(Primary Key) ?任意类型
Set 集 同样也是存放一系列相同对象的数据 它无序, set 提供更加丰富的方法 来操作 查询 存储 成员
HashSet 哈希集
1. 不能重复
2. 可以为空
3. 无序的(是不能按照 输入的顺序!!!!!) hashset 的顺序 是由 成员的hashcode 决定的 如果 hashcode 计算的规则不改变 则 遍历结果永恒不变
4. 线程不安全
transient 瞬态
1. 用 ArrayList 和 Comparatord 对扑克牌程序 进行全面的改写 包括 牌盒,玩家 , 发牌后的排序 功能
2. 回顾一下 这段时间 的 String , 数组 等 知识点
3. Math
Math 类位于 lang 包中,用来进行数学计算的
虽然 java 还有一个 math 包 但是 math 包中只有 相关的操作类 譬如 BigDecimal
4. JVM 中的垃圾回收的 浅谈
请注意,计算机没有真正意义的删除,如果计算机真的可以删除那 还有 那年 的 艳照门
对象 有 3 中状态
a. 瞬态 创建在内存中的状态 (红人)
b. 持久态 当对象被保存在 文件 数据库等物理区域的时候 (永垂不朽)
c. 游离态 当对象不被引用的时候 (孤魂野鬼)
回收是 jvm 不确定时间的动作
1.7+ G1 多线程回收 虽有分代回收的概念 但是已经不全部依赖这个方式来处理了
JVM JRE
5. JVM 中内存的构成
JVM 的虚拟机主要是 HotSpot VM
heap stack static constant pool
方法 理论上归于 堆 但是 由于属于 共享状态 所以 也叫非堆
JVM 的堆(heap)内存的分配:
a. 年轻代 (Eden, Survival x 2) 新建的对象 都进入 年轻代 区域
https://blog.csdn.net/woaini886353/article/details/124382091
b. 老年代 年轻代区域被清理过 数次(15)之后,还存活的对象 将进入 老年代
永久代(1.8+ 已经移除 使用 元空间(metaspace) 进行替代)
早期 老年代 使用 CMS 进行垃圾回收 后来使用 G1(Garbage First)
-Xms128 -Xmx512
5. instanceof 辨别 对象
多态性 是最契合的 (编译时都是 父接口, 运行时都是子实现)
A implements B
A a = new A();
a instanceof B = true ? false ?
B b = new A();
b instanceof A = true? false?
(A) b 可以 但是 如果 没有 instanceof的加持 可能会有风险!
ClassCastException 类转换异常
class A implements B;
class C implements B;
getSht(new C())
void getSht(B b){
(A) b // ClassCastException
if(b instanceof A)
(A) b
}
6. Exception 中的 finally
throws 写在方法后面的 抛出,可以抛出多个 不同的异常
throw 可以让我们 抛出一个 异常, 可以起到 通知 的作用。
throw 抛出一个异常 这个异常 有时候 不是我们想要的那一种。
自定义一个 符合项目业务逻辑的异常
自定义 的异常 起码要是 exception 的子类
sdfsdfsdfsd
7. Serializable 序列化
hashset 是一个 无序的 集合 1. 无序 (它的顺序 由成员的 hashcode 来决定,如果能保证 hashcode 的计算规则不变,则顺序永恒不变) 2. 不可以重复 相同的元素 后者 将被抛弃 3. 可以为空 4. 线程不安全
hashset 去重的原理 hashcode 不一样 同时 对象的地址也是不一样的
* 即便是 内容完全相同的 2 个对象 也可以放入到 hashset 中,如果 你想要 内容一样的对象 不能放入 hashset 你必须 重写 成员的 hashcode 和 equals 这2个方法
TreeSet
1. 可以为空吗? 元素不能为空
2. 可以重复吗? 元素不能重复
3. 有序吗? 无序的(他的顺序 是按照 成员的自然顺序来排列的)
注意 Treeset 并不是 什么时候都能使用。 TreeSet 能够显著的提升 查询成员的速度,前提是 有序。
所以成员不能为null。
任何 放入 treeset 的成员 都要可以被排序;
Map 一种数学上用来进行 索引追踪的 存储技术。 在 JAVA 主要是以 键值对的形式存储 各种数据类型
Map
java 中集合的可排序 涉及到的接口
interface Comparator<T> util compare int
a>b = +N a < b = -N a = b = 0
interface Comparable<T> lang compareTo int
Collections的一些收尾
1. 泛型(Generic)
用 宽泛的 不确定 类型 来替代 实际类型 让 代码变得更加的灵活
运行时 我们指定 具体的类型来替换 泛型 让类 具体化成对象
泛型只能是实体类型 不能是 原生类型
泛型可以用在类 中 抽象类中 也可以用在 接口上
泛型在定义的时候 可以有多个 Xxxx<a, b,c, ...>
DAO data access object 数据访问对象
方法中(不论静态 或者 非静态) 如何 动态的使用 泛型
泛型 还能够进一步的规范 类型
<T extends SUPERCLASS>
通配符的 泛型使用
<?>
定义泛型时 泛型的左右 必须类型一致
泛型作为 参数 进行接收的时候 可以 用 <?> 来接收所有类型
或者 用<E> 来确定类型
2. 内部类 (Inner Class)
a. 普通内部类
最大的作用 就是 标准化 内部类所构建的对象 并输出
Q: 如何 进一步 优化 标准化对象的构建 让外部的调用不知道 用的是什么对象,但是可以正常的获取内容?
b. 私有内部类
内部类 最有用的做法。 遮蔽 实现过程,通过接口暴露。让业务能够很好的隐藏 但又不影响外部调用者的使用
c. 匿名内部类
写在 类内部的子类 但是它没有名字。类如果没有名字 一般都是有 抽象类或者接口 直接实例化而来
nei bu lei
3. 设计模式 之 单例 工厂
设计模式 不是用来 简化代码的!!!
单例模式: 单个实例 singltone
如何 让对象在 java 的世界中只能存在唯一 一个
私有化构造方法
我们自己 实例化对象 并 static保存
判断输出 如果有 就输出原来的 没有 就新建
1. 为扑克牌 设置 可选择的洗牌方式 shuffle or random get
a. 数组整体随机 后 依次发牌
b. 随机数抽取 后 缩小数组
1. IO Input Output 输入 和 输出
1.4+ nio
仅仅 只是 读和写
.mp3 IO 负责将硬盘上 你指定位置的文件 以 二进制(原始)的方式读取到 播放软件中来
new Scanner(System.in) ; scanner
* 读和写 无非就是 文件 内存 网路
File 文件
构造 FIle 对象的时候 路径可以是 一个目录 也可以是一个文件
递归
最简单的 方法调用方法 来解决 不确定目标的信息查找上可以使用
他能用最简单的代码 和最优美的写法来完成 很多遍历的工作
递归切记一定要有趋于结束的条件
// 学生信息管理系统 添加几个功能
1. 在 启动之初创建一个 文件夹 和 文件 未来用于存放 用户的数据信息
2. 要准备 一个 方法 用来 每次启动 加载 用户信息 到内存中 方便后续的查询
stream 流 数字流 (流是比较原始的形态)
读写流
1. 字节读写流 (原始流)
InputStream 输入流 读取流
OutputStream 输出流 写入流
具体的实现流
FileInputStream 文件读取流 用二进制的读取方式来读取文件 的一个工具,如果你要读取 音乐 视频 等等 复杂的文件 ,请一定使用 FileInputStream
如果仅仅是读取文字性的内容,请不要使用!
* 所有文件 都是以二进制保存的,但是读取的时候 我们会用相应的工具去理解二进制的内容并呈现出来
* close 一个 什么都可以学不会 但是一定要记住的方法
字节写入流,向文件里直接写入的方案
FileOutPutStream 通常都是 将二进制的内容写入到文件中,可以选择 覆盖,也可以选择 追加 由我们在构造方法时来确定
由于是 二进制的操作,所以 我们的操作都将直接影响到 文件中的内容
* 虽然是直接操纵文件 我们还是要 注意 close 的使用!!!!
* 读写 流都是操作二进制的 所以都一样 都只适合使用在视频 音乐等 文件类型中
* 但凡看到 类名中由 stream 那他一定是 用 二进制字节流操纵内容的 工具
jar java archive
2. 字符读写流
Reader Writer
万物的存储 皆为 二进制
但凡 类名中 Reader 或者 Writer 的一定是 操纵 字符的类!!
如果 FileReader 不能读取整行信息
使用BufferedReader 对其进行包装 可以提供 readLine方法
Buffered 缓冲,数组 内存中 识别 \r
Q: 如果一个类名中 既有 Stream 又有 Reader 或者 writer 表示什么意思?
StreamReader 表示 字节流 转换字符流的 桥梁类
StreamWriter 表示 字符流 转换成 字节流的桥梁类
1. 为学生信息录入系统 添加 保存 录入信息的功能 文件名为 info.dat 文件的位置 项目的根目录
2. 启动时 读取文件 如果找不到这个文件 则 重新创建
3. 退出时 将 已经录入的学生信息 保存下来 按照 名字,年龄,性别,学号 的格式存储。同理 读取的时候 也用 , 进行分割 获取信息
reader&writer
IO Input And Output
Stream 原始的 字节流。 如果你只是需要读取文件中的二进制 内容 你必须选择 流的方式读取,再由相关的软件处理。
InputStream
OutputStream
FileInputStream read
FileOutputStream write
二进制是直接 操作文件的。所以 一旦修改就会立刻影响文件。(所见即所得)
不是所有的文件都需要用二进制的形式获取。比如文字类的东西。
Reader
Writer 他们都是 以字符流读取内容的
StreamReader 字节流转换成字符流的桥梁
StreamWriter 字符流转换成字节流的桥梁
缓冲区用于搜集需要转换的字符,然后一次性转成 二进制的。提高转换器的效率。但是如果你一定要指定立刻进行转换 可以使用:从内存的转换器中刷入文件中
flush
ObjectInputStream
ObjectOutputStream
能夠將 内存中的對象 鈍化到 實體文件中的技術
对象的钝化 需要序列化 Serializable
人类最想实现的 功能是什么
新白娘子传奇
分子化 -》 复制中 -》 拼起来
当 对象中有一些临时的数据 不需要保存 该如何处理?
transient 瞬态的标识 当使用 这个标识修饰变量的时候 表示这个变量在钝化过程中 不存储数据
一般来说如果 你想要序列化对象的时候 内容过于复杂 ,你可以使用 transient 关键字 标识那些复杂的变量 让其不进入 序列化中
A -》 B -》 C -》 List<D>
list transient
一个文件中多个对象 如何持久化?
按顺序进行存储 同样也要按照顺序进行读取!!!!、
需要注意 数据放在前面 对象 放在后面
ByteArrayInputStream
ByteArrayOutputStream
二进制数组(缓冲)的读写流 内存的读写流
核心的用途 就是把 一些 内存中运算的结果 存储在一个 临时的缓冲区中
等达到 你定义的存储要求后 可以写入(钝化)到某个指定的地方
RandomAccessFile
灵活 快速的访问文件指定位置的一个工具,由于实现中包含了 NIO的内容 所以 无论处理本地文件数据 都非常的方便
重要的是 它可以自由的访问 文件的任意位置。
Skip