Javase
2021-08-27 18:01:15 0 举报
AI智能生成
javase导图
作者其他创作
大纲/内容
单行注释
多行注释
会生成帮助文档
javadoc注释
注释
JDK与jre与jvm三者关系
可自己命名的/且遵守命名规范,不能与关键字重名
标识符
定义数据类型关键字
定义访问权限修饰符关键字
关键字
字面值
实例变量
静态变量以static关键字修饰
静态变量
成员变量
形参
在方法中定义
方法局部变量
在代码块内定义
只执行一次,且在类加载时执行
static修饰的代码块
不常用
普通代码块
代码块局部变量
局部变量
变量
整数型通常默认为int型
byte、short、int、long
整数型
这个要在后加f
float
默认是double型
double
浮点型
boolean
布尔型
'\'表示换行 ,‘\\t’表示空格
char
字符型
四大类八小种
byte short int long float double boolear char
1 2 4 8 4 8 1 2
口诀
基本数据类型
例如:类 接口 数组
String也是引用数据类型
引用数据类型存储的是对象的内存地址
引用数据类型 赋值null
大到小自动
小到大强转
char和short平级
数据类型的转换
数据l类型
二进制
字节编码
+ - = * / % ++ --
算数运算符
=
赋值运算符
== != < > <= >= instanceof(检查是否是类的对象)
比较运算符
& | ! && || ^或
逻辑运算符
<<(乘2的除自身的位次) >>(除2的位次)
>>> & | ^ ~
位运算符
(条件表达式/布尔)?表达式1:表达式2
三元运算符
运算符
if else if switch
选择结构
for 、while、do~while
break(跳出)
continue (执行下一个)
控制语句顺序
循环结构
控制语句
提高代码复用性
提供某个功能
作用
修饰符
返回类型
逗号隔开
nt…args
语法
类型… (三个点)
个数是0~n个
且在形参列表中最后一个
且只能是一个
可以当成一个数组来看待
有lenght属性可遍历输出
也可以传一个数组
可变长度参数
方法体
有返回类型 return
没有返回类型/void return 可不写 写代表 方法的终止
return
返回值
基础语法:
类名.方法名
同类 直接方法名
static修饰
调用:
定义b不分配运行所属内存
调用时才会分配
方法定义在内存分配与变化
方法/成员变量
压栈/弹栈
栈帧指向顶元素
特点 先进后出
栈stack
内存分三块(多线程时会有多个栈)\t
JAM
不同的返回类型
不同的形参
相同的名字
主要用在功能相似的方法地方上
方法的重载
方法/函数
自身调用自身
递归很消耗栈内存
一直调用方法 一直压栈 没有弹栈
容易发生栈内存溢出
所以一定要有停止条件(大概率也会发生栈内存溢出)
递归
java语言基础
提高系统安全性
让对象变成真正的独立体
可重复使用,适应性强
特点
属性私有化private
get/set方法
可在方法类添加限制条件增强安全性
对外提高操作入口
方法步骤:
封装
最重要的是有了继承才能有以后的方法的覆盖和多态机制
修饰符 class 类名 extends 父类
语法:\t
定义
只支持单继承,不支持多继承
私有不支持继承
构造方法不支持继承
其他数据都可以被继承
如果没有显示继承,会默认继承Object类
Object类是根父类,其父类也提供了某些方法 任何一个类都object特性,也可重写父类的方法 例如tostring equals 等等..
继承
存在继承或者实现关系
有覆盖操作
前提
父类 索引=new 子类对象
父类类型引用指向子类对象
调用
向上转型(子类 转成—》 父类)自动
向下转型(父类 转成—》 子类)强制 (需要加强制转换符)
且俩种需有继承关系
强转最好加判断条件
转型
降低耦合度 提高扩展力
多态
三大特征
优:耦合低 可扩展性强 组件复用性强
缺:前期投入成本高,大量系统分析与设计
面向过程编程
POP
OOP 面向对象编程
OOD面向对象设计
OOA面向对象设计
面向对象开发软件生命周期OO面向
面向对象/过程
可存储值
对象的内存地址 指向对象
存储实例变量
栈内存
对象里有局部变量
局部变量可存储内存地址
存储对象
垃圾回收机制 System.gc()
堆内存
class字节码文件
常量池
方法区
JVM内存结构
一个是main主线程
一个垃圾回收线程
一个程序的启动至少开启俩个线程
修饰符加方法名 且方法名与类名要一致
自带无参构造
如果自定义构造方法,系统将不再默认提供
且可以重载
new 构造方法名(实参列表)
调用:
1、创建对象
2、创建对象的同时,初始化变量的内存空间
3、也可设置默认赋值
构造方法
也是变量
保存自身内存地址 指向自身
存储在堆内存中,表示当前对象
特点:
可用在实例方法中,代表当前对象 this.
可用在构造方法中调用其他的构造方法 this()
不能使用在静态变量中 因为静态变量存储在方法区中
用法:
this
静态方法
修饰
类名. 调用
在本类 中直接访问
如果属性的属性值不会改建议使用static修饰
static修饰都具有类级别的特征 与对象无关
在main方法之前之前执行
因为在方法区 而main方法在栈内存
且只能执行一次
静态代码块
static 修饰的代码块
模板级别
看具体需求:例如日志记录
直接类名.调用方法 不用new对象
很方便
封装工具类
作用:
static
表示最终的(不可变的)
类 无法被继承
方法无法被覆盖/重写
不可被重新赋值
修饰实例变量需要手动赋值,系统不会默认赋值
修饰的对象无法被垃圾回收机制回收
称为常量
修饰变量
无法修改的类变量
public static final 类型 常量名 = 值;
以常量名命名须用大写
java语言规范
final与static联合使用
final
访问父类属性
不能出现在静态方法中
调用父类成员方法
要放在第一行
在构造方法里调用
调用父类构造器
super.调用 属性/方法 super(实参)构造方法
调用父类指定操作
super
检验 是否为类的对象
insstanceof
表示当前文件路径
如果类名不在同一个包下要假设包名
import 导包
java.lang包下的不用导 包里包要导
package/import
对象之间的转型 最好加个instanceof判断
public
private
protected
省缺的
访问权限
无法被实例化 无法new 对象
抽象方法加上abstract修饰
没有大括号 以分号结尾
需要被子类重写
抽象方法
由于l类不能被实例化
只能用多态才能调用到子类的方法
普通方法
可以定义抽象方法和普通方法
只能被继承
所以抽象类不能和final关键字写到一起
用abstract修饰
抽象类
interface修饰
implement实现接口
接口是引用数据类型
接口是完全抽象的 特殊的抽象类 (抽象类是半抽象)
支持多继承 ,多实现
自动 加上 public static final 修饰
常量
所有的元素都是公开的 会自动加上public abstiact
接口中包含俩部分
抽象类能有普通方法 接口全是抽象方法
抽象类半抽象 接口完全抽象
抽象类有构造方法 接口没有
接口和接口存在多继承 抽象类只能单继承
接口中只能出现常量和抽象方法
以后接口的使用会比抽象类多 接口一般是对“行为"的抽象
接口与抽象类的区别
普通接口
标志接口是给java虚拟机看的
例如IO流中的正/反序列都要实现标志接口Serializable
标志接口
接口
抽象类和接口生来就当爹的 精辟!
猫是动物 继承
我有一支笔 实例变量
厨师像菜单 实现接口
类与类之间的关系
私有化构造方法
对外提供唯一实例
单例模式
面向对象编程
Jdk类库的根类
所有的类都会默认继承Object类
不重写时会打印 类名@对象的内存地址转换为16进制的形式
输出会默认调用tostring方法
转换成字符串输出
sum公司也建议使用
toString方法
判断俩个对象是否相等
默认是比较俩个对象的内存地址
我们可重写equals方法 使的他比较的对象里面的内容
string类以重写了equals方法和toString方法
equals方法
返回的是哈希码
可等同内存地址
因为内存地址通过哈希算法转成数字了
hashcode方法
wait(线程等待)与notify(线程唤醒)
常用方法
Object类
实例
静态
局部
匿名
分类
只能使用一次
且可直接new 接口 和抽象类
然后对抽象方法进行重写
匿名内部类
常用
内部类
父类/内部类
分支主题
直接赋值
new 对象赋值到构造器里
引用数据类型
双引号括起来的都是string对象
存储在字符串常量池中
字符串相同时常量池不会新建,直接用
字符串.charAt(下标) 返回字符串下标的值(掌握)
Contains 是否包含后面的字符串(掌握)
endsWith判断以某个字符串结尾(掌握)
Equals 比较俩个字符串是否相等(掌握)
Equalsignorecase判读俩个字符串是否相等 不管大小写(掌握)
Byte[] 数组 getBytes()字符串对象转化为字节数组 (掌握)
indexOf() 判读当前字符串第一次出现的下标(掌握)
Length 长度(掌握)
Isempty 判断字符串是否为"空字符串“(掌握)
Lastindexof() 字符串最后出现的下标
Startswith 判断以某个字符串开始 返回值对错
Substring(a,c) 截取字符串a截取 c长度
toCharArray 将字符串转换成char数组
Tolowercas 转小写
touppercase转大写
Trim 去除前后空白
String.Vaueof( ) 将非字符串转换成字符串 静态方法 类名点 调用
Println()这个方法里面有vaueof 将非字符串转换成字符串 自动调用这个 自动而这个调用tostring方法
方法
String类
频繁+号拼接 会浪费方法区常量池的内存
所以我们用StringBuffer类进行拼接
New 对象初始化 数组底层是byte【】 数组append()追加会自动扩容
Stringbuider类也是字符串拼接append()追加
StringBuffer类线程是安全的
俩者的区别
StringBuffer类
JDK1.5以后提供了自动拆箱和装箱
基础类型对应的8个包装类
Date类 无参构造方法(精确到毫秒)
直接调用输出即可
用构造方法格式化
yyyy年(年是4位数)MM 月(2位数) dd 日 mm 分 ss 秒SSS 毫秒 (三位数)
SimpleDateFormat类
日期格式化
日期相关类
Dcunauformat数字格式化类
主要用于财务软件里面
BIgdecimal类精度极高
数字相关类(了解即可)
new 对象 索引调用
或者匿名调用
里面有一些方法,直接传参即可
Random 随机数类
可以一枚一枚列举出来的
例如布尔类型只能是ture flase俩种类型
日常开发中 不能只有俩种情况 还有多种
枚举也是引用数据类型 生成class文件 枚举类中的每个值可看做常量
enum 枚举类名{ 值,值}
语法:
我们满足什么类型就可以返回自己定义的值
有多种返回标志结果
例如修饰在方法上时
Enum 枚举类
System.out.println() 【println是println类的方法】
System.gc() 建议启动垃圾回收器
System.currentTimeMillis() 获取1970年到当前的总毫秒数
System.exit (0) 退出JVM
System类
文件和路径名的抽象表现形式
可对文件目录进行操作 但不能读写文件
创建对象 在构造器传入文件路径
索引.exists()判断文件是否存在
索引.createNewFile()以文件的形式创建
索引.mkdir 以目录的形式创建
索引.mkdirs 多重目录
索引.getAbsolutepath()绝对路径
getname获取文件名
isFile判断是否文件
lastModified 最后一次修改时间 (毫秒数)
length大小
listfiles数组方法 获取这个目录全部子文件(循环打印)
File类
常用类
忘记了查帮助文档
类
引用数据类型 分类object (相当于容器)
可存储基本数据类型与引用数据类型
数组存储在堆内存中
存储对象的话 是存取对象的内存地址
所有数组对象都自带length属性
有下标 以0开始 以一递增
数据类型[] 索引={存储的值,对象,数组,。。。}
数据l类[] 索引=数据类型[长度]
定义:
索引[下标]
一维数组
数据类型[] [] 索引={{存储的值,对象},{数组,。}。。}
索引[外层下标][内存下标]
调用/赋值
二维数组
多维数组
Arraylist
动态数组
打印输出
倒叙
从0开始 到length结束 递增
正序
for
左边数组类型 索引:数组索引
打印 索引
foreach
遍历
冒泡
选择
排序算法
二分法查找
查找算法
常见算法
里面封装了这些常见的算法
因为用Static修饰
类名点调用
Arrays工具类
将ints 数组 起始位置下标1 拷贝对象 ints1 起始位置下标3 长度为2
进行拷贝
数组扩容
数组
控制台的异常都jvm打印的
异常在java中以类的形式存在
jvm在执行异常程序时会自动new异常对象
Exception(编译时异常)或者RuntimeExcention(运行时异常 )
概述:
提醒程序员
让程序更加健壮
1编写一个类 继承 Exception或者RuntimeExcention
无参构造
surper传入字符串的索引
带有String参数的有参构造
2:提供俩构造方法
自定义异常
throw new 异常类 手动抛出异常 即可
在需要发生异常的方法里
调用自定义异常
thorow抛出异常 上报给调用者 在方法声明的位置上使用
抛出
catch可写多个 原则从上到下 从小到大
使用try..catch语句进行异常捕捉
finally最后一定执行的 一般流的结束 会放在这里
捕捉
对异常的处理机制
编译时异常发生概率比较高 编译器会爆红
运行时异常发生概率较低
编译时y异常与运行时异常的区别
异常
数组是集合
集合实际上就是容器/载体 可以一次容纳多个对象(存储的是内存地址)
可以容纳其他类型的数据
使用不同的集合就会使用不同的数据结构
集合接口与集合类都在java.util包下
概念
拿到迭代对象
hasNext()(判断是否还有下一个元素)
next()(拿到下一个元素 并返回)
remove
迭代对象的方法
继承Iterable接口
有序可重复
存储元素有下标 从零开始以一递增
底层采用数组数据结构,非线程安全 可用工具类来抵消线程安全问题
默认初始化容量为10 在构造器里面里面初始化
你也可以自己new 对象时手动初始化
底层是object数组
扩容到原容量的1.5倍
检索效率较高 向数组末尾添加元素效率高
但随机增删元素效率低
无法存储大数据量
优化:建议预估记元素个数 给定一个初始化容量
Arraylist集合(常用)
底层采用双向链表
在空间存储的内存地址不连续
随机增删元素时不会有大量元素位移,因此随机增删效率高
以后开发中,如果遇到随机增删集合中元素的业务比较多时,建议使用Linkedlist
优点
不能通过数学表达式查找元素内存地址
缺点
链表数据结构(双向链表)
链表基本单元是节点Node。
第一:存储的数据结构。第二:下一节点的内存地址
对应单向链表来说,任何一个节点Node中都有俩个属性:
优点:随机增删效率高
缺点:查询效率低 (每一次都从头开始找)
链表数据结构
链表
Arraylist:把搜索发挥到极致
linkedlist:把随机增删发挥到极致
//现在加元素都是往末尾加 所以Arraylist用的比Linkedlist多
arraylist/linkedlist
Linkedlist集合
也是数组结构
vector集合(很少用)
实现类
add ( int指定位置,添加元素)
get(int指定位置) 返回指定位置的元素
Indexof() 返回第一次出现的索引 没有返回-1
Lastindexof 最后一次出现的
Remove 移除下标
Set {替换 第几个元素 下标,重新赋值)
list接口常用方法
List接口
无序不可重复
存储元素无下标
new在创建对象时 底层创建实现上了new了HashMap集合
向Hashset集合存储元素,实际上是存储到HashMap中
HashMap集合是哈希链表数据结构
hashset集合不可重复 我们可以往hashset集合里面添加元素
然后在把这个索引传参给 我们arraylist 实现类的构造方法里面
就可以用arraylist遍历里面元素倒序正序都可以 然后用arraylist的get方法打印
使用遍历
Hashset集合
底层是TreeMap集合
Treeset集合放数据时会将数据放入TreeMap中
TreeMap底层底层是二叉树结构
放在TreeSet集合中的元素需要实现java.lang.Comparable接口。
继承Comparable《排的类》接口
并且实现compareTo方法。equals可以不写。(String类型已经重写了)
返回0 value覆盖 >0右树上找 <0 左数上找
TreeSet集合可排序的第二种方法 使用比较器的方式
编写比较器类 实现comparator接口 并且重写compare方法
然后在Treeset对象的构造方法里传入比较器对象
排序
Treeset集合
元素可自动排序
sortedset接口
Set接口
被继承
这里面只有Arraylist,linkedlist,vector,Hashset,TreeSet是实现类
其他全部都是接口
总结:
索引.add向里面添加元素 new对象 和基本数据类型
因为在jdk8后会自动装箱拆箱 把内存地址加进去
索引.size 集合的长度
索引.clear 清空集合
索引.contains(obj某元素) 判断集合里面是否包含 某元素 返回布尔值
索引.remove(obj元素) 删除集合中的某个元素
索引.isEmpty() 判断集合是否为空 返回布尔值
索引.toArray() 把集合转成数组
Collection常用方法
是collection即子类中都能使用 (map不能用)
第一步:
获取集合对象的迭代器对象Iterator
第二步
以下俩个方法是迭代器对象的Iterator的方法:
hasNext()如果仍有元素可以迭代ture 返回布尔值
next()返回迭代下一个元素 元素 object
获取以上迭代器对象 开始迭代/遍历集合
迭代器最好里遍历循环近一点,以便数据结构发生改变 要重新获取
迭代器调用
for循环遍历
foreach循环遍历
集合遍历
Collection超级父接口(单方式存储)
Map集合与collection集合没有关系
map集合以key和value这种键值对的方式存储元素
key和value都是存储对象的内存地址
所有的key都是无序不可重复的
key和set集合存储元素的特点相同
key起到主导的地位,value是key的附属品
哈希表是一个数组和单向链表的结合体
哈希表数组和单向链表这俩种数据结构融合
充分发挥他们各种的优点
无序,不可重复
用equals方法保证hashmao集合的key不可重复
如果重复就覆盖
hashmao集合部分元素放到Hashset集合中所以HashSet集合中的元素也需同时重写hashcode+equals方法
v.map.get(k);
放在hashmap集合的key部分的元素,以及放在hashset集合中的元素,需要同时重写hascode和equals方法
jdk8之后如果哈希表这种数据结构单向链表超过8个
会变成红黑树数(二叉树)据结构,红黑树上的节点数量小于6又会变成单向链表
非线程安全的
注意
Hashmap集合
底层是哈希链表数据结构
线程安全
存:
取:
索引.getproperty(key);
properties属性类对象
hashtable集合
实现
TreeMap集合
sortedMap接口
clear 清空map集合
containskey(key) 是否包含key
containsvalue(value) 是否包含value
get(key) 通过key获得value
Isempty 判读元素个数是否为0
Keyset 获取 map集合所有的key
put(k,v)添加键值对
remove(key)通过key删除键值对
Size 获取键值对的个数
Values 获取所有的values
通过set《泛型》 获取 map.seyset() 获取key值
然后通过 迭代器 Iterator 进行遍历
第一种
通过forEach循环遍历
第二种
Set<map.Entry《k,v>> entry set()
将map集合全部转换成Set集合。
set集合的类型是Map.Entry
第三种
第三种方法开发效率比较高,转成set集合在用foreach循环遍历
遍历Map集合
Map超级父接口(键值对方法存储)
俩大类
Collections:是集合的工具类
Collections.synchronizedList(Arraylist索引);
可以把Arraylist数组非线程安全转换成线程安全的
Collections.sort 排序 对list元素排序需要保证list集合中的元素实现compareble接口
COllections。sync。。。实现线程安全
如果set想实现排序 要对set进行转化 转成 list
new对象 把set索引传入 list构造器中
集合工具类
Arraylist:底层是数组
Linkedlist:底层是双向链表。
Vertor:底层是数组,线程安全,效率低。使用少。
HashSet:底层是HashMap;放到HashSet集合中的元素等同放到HashMap集合Key部分了
HashMap:底层是哈希表。
Hashtable:底层也是哈希表,只不过线程安全的,效率较低,使用少。
Properties:是线程安全的,并且Key和value只能存储字符串String
TreeMap: 底层是二叉树,TreeMap集合的key可以自动按照大小排序
所有的实现类
1.每一个集合对象的创建(new)
2.向集合中添加元素
3.从集合中取出某个元素
4.遍历集合
LinkedList
HashSet、(hashmap的key需重写hascode+equals)
TreeSet
HashMap
Properties
TreeMap
5.主要的集合类:
集合需要掌握什么内容?
总结
集合
指定数据类型
使集合的元素更加统一
想要调用存储对象时
需要转型
加l了泛型后可不用转型直接调用
不加泛型时默认是object类型
也可配合多态使用抽象类、接口,重写他们的方法,拿到构造器泛型 循环判断 直接调用 如果调用子类特有方法需要转型
类名<名称自己定义>
类名<传入数据类型> 索引=new 类名<>();
JDK8的新特性
后面<>表示自动判断
自定义泛型
泛型
byte[]数组装
标识符=0 循环判断 标识符=对象索引.read(数组)!=-1
打印控制台
new String(读取文件,从那里开始,从那里结束/标识符)
关闭流/包装流
常用方法:
Int available()返回流当中剩余的没读到的字节数量
Long skip(long n)跳过几个字节不读。
FileInputStream(掌握)
创建数组
标识符 循环
对象索引.Write(写入文件,那里开始,标识符结束)
刷入硬盘
关闭l流
默认是覆盖/追加的话要在构造方法那里加上true
FileOnputStream(掌握)
用char数组装 方法都差不多
FileReader
FileWrter
文件专属:
inputSttreamReader
OnputStreamWriter;
转换流:(字节转字符)
不需要带自定义数组
可读取一行readline()
BufferedReader
BufferedWriter
创建节点流
创建包装流 节点流传入包装流的构造方法中
创建标识符 String类 赋值null
while循环 判断标识符=读的没一行!=null;
输出控制台
关闭包装流即可
BufferedInputStream
BufferedOutputStream
缓冲流:
DataInputStream
DataOutputStream
数据流
PrintWriter
PrintStream标准的字节输出流。默认输出到控制台
且不需要手动close()关闭
printStream(掌握)
标准输出流:
参与序列化/反序列化的对象
对象类必须要实现Serializable接口,接口是标识接口
否则会出现序列化异常
一次序列化多个对象,用数组装
序列化
ObjectInputStream(掌握)
反序列化(拿到读到的obj)判断往下转型 转成数组 然后打印输出
反序列化
ObjectOutputStream(掌握)
凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列号版本号。
这样即使该类的代码修改,版本号不变,java虚拟机会认为是同一个类
手动生成序列号
Private static final long serialVersionUID=23442342L;
结论
对象专属流
Java.IO包下需要掌握的流有16个
在java中只要"类名"
字节流,一次读取一个字节8byte
万能流,可读取视频,图片,声音
以Stream结尾的都是字节流
一次读取一个字符
方便读取普通文件
视频、声音、word等文档不可读取
以Reader/Writer 都是字符流
注意:
I: Input(输入)/Read
最后需要.flush刷入键盘
O:Output(输出流)/Write
输入与输出
所有的流动实现了:Closeable接口 都是可关闭的
都有close()方法 用完要关闭 不然会耗费很多资源
所有的输出流都实现了:Flushable都是可以刷新的
都有flush方法 在最终输出之后要记得刷新一下
刷新的作用就是清空管道
如果没有可能会导致丢失数据
IO流文件的读写
properties;是map集合,key和value都是String类型
很好的设计理念,编写好代码时不需要改动 直接在配置文件更换value值就可以调用到不同对象
反射机制
JDBC可能会用上
内容格式Key=valueKey=value
java规范中 属性文件建议以.properties结尾
配置文件
IO流和properties属性集合的联合使用
IO流
一个java程序中至少有俩个线程并发,main方法主线程 垃圾回收线程
使用多线程后,main方法结束了只是主栈结束了,还有可能其他的栈在压栈弹栈
进程内存独立不共享
但是栈内存独立,一个线程一个栈,每个栈之间互不干扰各自执行各自的,这就是多线程并发
多线程机制就是提高程序处理效率
实例变量:在堆中 成员变量包括实例和静态
静态变量:方法区
局部变量:栈中
局部+常量永远都不存在线程安全问题
因为局部变量存在栈中 局部变量不共享(一个线程一个栈)
堆只有一个
方法区也只有一个
堆和方法区都是多线程共享的
java三大变量
创建一个类 继承Thread类
重写run方法
new 对象
Start方法启动
以Thread类形式创建
创建一个类实现Runable接口
再new 一个Thread对象 把接口对象传入Thread构造方法中
start启动线程
或者直接匿名调用 接口
接口比较常用 因为java只能单继承却能实现多个接口
Runable接口的形式创建
有返回值
可以获取返回值 获取线程的执行结果
效率较低,在获取返回值时,需要线程执行完才能返回值,会造成堵塞
实现Callable接口
实现方法
新建状态
就绪状态
运行状态
堵塞状态
死亡状态
线程的生命周期
setname修改线程名字(默认的名字是Thread 0开始往后自增
getname获得线程名字
Thread.currentThread() 静态方法 获取当前线程对象(出现在那个栈中就获取那个栈的线程)
Thread.sleep() 静态方法 让当前线程进入休眠状态 参数跟的是毫秒数
Interrupt 唤醒线程 (比如你让一个线程睡眠一年,用这个方法可直接唤醒他)
实例方法
合并线程
就是并发变成同步
不是栈合并 是栈等待了
join合并线程
容易丢失数据
stop终止线程(已过时)
定义一个布尔标识符
初始值为true
if判断标记为true 执行 在else中return结束方法
在return之前也可以保存好数据在结束方法
终止线程时调用这个对象的标识符改成false
常用终止线程的方法
setpriority设置线程优先级
getpriority获取线程优先级
最低1默认5最高10
Yield 静态让位方法 不是堵塞 是让位当前线性
运行阶段回到就绪状态 就绪之后他有可能又会去抢占
java调度
抢占cpu时间片
java采用的
抢占式线程模型
平均分配时间片
有些编程语言也采用这个
均分式线程模型
调度模型(了解)
线程的方法
synchronized(){ 线程同步代码块数据 }
小括号里面传入的是共享数据的对象
多线程并发(效率高)
异步编程模型(并发)
俩个线程存在等待关系(效率低)
同步编程模型(排队)
模型
同步代码块(灵活)
实例方法上使用synchronized
在静态方法上使用synchronilzed
FutureTask方式.实现Callable接口
synchronized四种写法
线程同步机制
synchronized会让程序效率降低(用户吞吐量降低,用户体验差)
第一种方案:尽量使用局部变量代替实例变量和静态变量
第二种方案:如果必须要用实例变量,那么考虑创建多个对象
第三种方案:最后前面俩个不行的话再synchronizedx线程同步机制
以后开发怎么解决线程安全问题?
间隔特定的时间,执行特定的程序
例如:备份操作
Java.util.Timer类
定时任务的对象要继承TimerTask 线程
要重写run方法
实现定时器
定时器
一般守护线程都是一个死循环
所有的用户线程结束,守护线程自动结束。
主线程main也是用户线程
用在那里?
进行数据定点备份
一类是:用户线程
一类是:守护线程(后台 线程)
java语言线程分为俩大类
在启动线程之前
用setDaemon(true)方法
设置为守护线程
守护线程
wait和notify是所有类中都有的不是线程对象的,
因为所有类都继承object类
所以调用时不是通过线程对象调用
简介
当前线程
让活跃的对象线程进入等待状态 无期限 直到被唤醒为止
wait方法作用
唤醒等待线程 对象点调用 唤醒当前线程
对象不是线程对象
Notify
Object类中的wait(线程等待)和notify(线程唤醒)方法
一般wait与notify联合使用
还有notifyALL是唤醒 在这obj对象上的所有线程
比如先new了一个o对象
然后o对象开启了俩个线程 一个A一个B
调用时用o索引.方法调用
生产者与消费者
多线程
可以操作class字节码文件
Class c=Class.forName(完整包名类名)
Class c=对象.getClass()
Class c=类型.class
c返回的是类型 还要将其实例化才能用
创建拿到对象三种方式
Newinstance方法 (jdk9已过时)
拿到对象类型 然后对象.newinstance
实例化对象
调用时要保证有无参构造
Java.lang.class 代表字节码文件
获取反射对象
对象实例化
对象。getDeclaredfield ("属性名")
获取属性
Set(对象,"修改的值")
get(对象) 获取值
想访问私有的
setAcceessible(true)打破封装
获取父类接口
getsuperclass获取父类
getinterfaces获取接口
接口是多个 所以是数组 可以遍历获取
反射的方法
例子
Classc=Class.forName("practice01.EEE");
//实例化
Objecto=c.newInstance();
//获取方法
//调用什么对象的什么方法方法传参
//输出返回值
System.out.println(jieguo);
调用方法
Method 字节码中的方法字节码
调用构造方法:
//获取构造方法
getDeclaredConstructor( 类型.class ….)
//调用构造方法
构造方法的索引.newInStance(传入参数)
Constructor 字节码中构造方法字节码
拿到反射对象实
Object类型 多态索引.newinstance实例化
Fieldfield=c.getDeclaredField("age");
//给属性赋值obj的age属性赋值19
//这里也可以赋值到配置文件里修改配置文件的东西
修改属性
Field 字节码中的属性字节码
反射机制相关的重要的类
java代码写一遍 在不改变原代码的基础
可以做到不同对象的实例化
非常灵活(符合OCP开闭原则:对象扩展开发,对修改关闭)
后期:学习的高级框架,工作过程中也使用高级框架
包括:ssh ssm
这些框架底层实现原理:都采用了反射机制
所以学习反射机制有利用你去理解框架底层原代码
反射机制的灵活性
可拿一个整个类的到属性方法源码
反射反编译(了解即可)
通用方式 即使代码换位置也有效
通用方式的前提是:这个文件必须在类路径下
凡是在src下的都是类路径(其实是out class文件 现在就当这么理解)
如果将来项目放到linux上运行的话 linux没有C D盘符时 这个通用方法也依然有效
String path=Thread.currentThread().getContextClassLoader().getResource("输入从src开始的文件名").getPath();这种方式获取的是绝对路径是通用的
Thread.currentThread()当前线程对象
getContextClassloader()线程对象的方法,可以获取当前线程的类加载对象
getResource()获取资源
获取通用绝对路径方法
文件路径问题
获取属性配置文件 配置文件 key=value
属性配置文件xxx.properties必须放在类路径下
且后缀名properties不能写
这种方式连IO流的影子都不用写
直接获取key值
ResourceBundlebundle=ResourceBundle.getBundle("Peizhiwenj\\\\classinf");
//资源绑定器只获取属性配置文件后缀名不能写
String text04=bundle.getString("Text04");
System.out.println(text04)
//此时输出的是value 如果这配置文件value保存是路径名
我们就可以通过反射机制来传入这个路径名 调用这个类
例
资源绑定器
1用字符串获取 再传入io流中
InputStream inputStream=Thread.currentThread().getContextClassLoader().getResourceAsStream("Peizhiwenj\\\\classinf.properties");
2直接用io流获取
还有第三种方法 sum公司写好的资源绑定器
获取文件绝对路径通用三种方式
通过IO流读取配置文件
创建propertier集合
把读到的文件
放入 propertier的load方法里面
关闭流
然后获取getproperty(key) 路径名
然后放入 class.forName中
IO与propertier属性集合与反射机制联合调用
启动类加载器
扩展类加载器
应用类加载器
类加载器(了解)
注解Annotation是引用数据类型 编译生成xxx.class文件
语法格式:
【修饰符列表】@interface 注解类型名{}
@interface修饰 属性、数据类型 变量名();
调用时要给属性没有值时要赋值
有属性必须赋值
如果后面有default 值 ;
可以给属性赋值一个默认值
这样在调用时可以不赋值
自定义注解
@注解类型名
可出现在类、属性、方法、变量上等。。。
注解还可以出现在注解类型上。
调用格式
Java.lang包下的注解类型:
Deprecated用@Deprecated注释的程序元素(掌握)
告诉其他程序员不鼓励使用,通常是因为他很危险 或存在更好的选择 就是告诉别的程序员 这个程序以过时
Override表示一个方法声明打算重写超类中的另一个方法声明(掌握)
Suppresswarnings 指示应该在注解元素中取消显示指定的编译器警告(不用掌握)
JDK内置了那些注解
用来标注注解类型的注解;称为元注解
常见的元注解有:以下
是元注解 用来标志 被标志的注解
能出现在什么位置上
@Target(ElementType.METHOD) //只能出现在方法上
Target注解:
元注解,这个用来标注被标注的注解最终保存在那里
例:
@Retention(RetentionPolicy.SOURCE)//表示保留在java原文件当中
@Retention(RetentionPolicy.CLASS)//表示保留在Class文件当中
@Retention(RetentionPolicy.RUNTIME)//表示保留在class文件当中,并且可以被反射机制读取到
Retention注解
元注解
注解
Javase
0 条评论
回复 删除
下一页