导图社区 职场必看!Java编程思想思维导图
如何从0逆袭Java编程大师?一张思想思维导图带你了解Java编程。本图共有二十一章,从各个方面为你提供解答,内容详见且条理清晰,注意从十七章后知识点等多,更详细,赶快收藏下图学习吧!!!
编辑于2018-12-20 07:05:26Java编程思想思维导图
第一章 对象导论
抽象过程
汇编语音
底层轻微抽象
命令式语言
C、BASIC
对汇编的抽象
解决问题时
基于计算机的结构
不会基于需要解决问题的结构
只针对待解决问题建模
世界某些特定视图
LISP
所有问题最终都是列表
APL
所有问题都是算法形成的
不能解决所有问题
面向对象OOP
表示问题空间的元素
不会受限于任何特定类型的问题
异常处理:处理错误
错误 ->置于编程语言中
Java内置异常处理并强制使用
每个对象都提供服务
把对象想象成‘服务提供者’
开发理解程序
提高内聚性,不试图做更多的事
被隐藏的具体实现
访问控制
让客户端程序员无法触及他们不应该触及的部分
允许类库设计者改变内部分工作方式
关键字
public
任何类都可以访问
protected
仅继承的类可以访问
default
仅同包目录下的类可以访问
private
仅自己能访问
复用具体实现
组合
现有类-->新的类
极大的灵活性
继承
编译器 -->继承类 -->编译时的限制
继承
父类和子类差异
直接在子类加方法
覆盖方法
每个对象一个接口
类
问题空间元素<-->解空间元素
接口
确定某一特定对象,所能发出的请求
伴随多态的可互换对象
特定类型 --> 父类对象
不能依赖特定类型的代码
函数调用
前期绑定
非面向对象编程
运行代码的绝对地址
后期绑定
面向对象编程
编译器-->确保调用方法的存在
运行时-->计算代码的地址
Java编译器
how?
对象中存储信息-->计算方法地址
动态绑定会默认的
C++需要virtual关键字
向上转型
单根继承结构
好处
保证所有对象具有某些功能
极大简化参数传递
容易实现垃圾回收
容器
集合
List
存储序列
Map
关联数组
Set
无重复集合
泛型
向下转型 -->Object -->具体类型
参数化类型
对象的创建和生命周期
C++
追求最大执行速度
编写时确定:存储空间和生命周期
存储
堆栈
静态存储区
Java
存储
堆的内存池
逻辑假设
“是一个”与“像是一个”的关系
是一个
继承至覆盖父类
纯粹替代
像一个
在子类中添加新的接口元素
第21章 并发
并发的多面性
并发方式
进程
操作系统级别
进程相互隔离
线程
Java支持
抢占式
更快的执行
多处理器、多个任务→提高吞吐量
↑运行在单处理器上的程序性能
阻塞
基本的线程机制
定义任务
实现Runnable接口,编写run()方法
加入一个线程
join()
使用Executor
客户端和任务执行间的间接层
允许管理异步执行的任务,无需显式管理线程的生命周期
shutdown()
防止新任务提交给Executor
当前线程继续允许之前提交的所有任务
newFixedThreadPool
预先执行代价高昂的线程分配
newCachedThreadPool
为每个任务创建一个线程
newSingleThreadExecutor
多个任务将排队
任务会顺序执行
所有任务使用相同的线程
序列化任务,不需要同步共享资源
Thread类
Runnable对象→Thread构造器
线程调度机制是非确定性的
早期JDK不会频繁对时间切片
休眠
sleep()
InterruptedException
优先级
线程的重要性→调度器
JDK 10个优先级
Windows 7个且不固定
只使用
MAX_PRIORITY
NORM_PRIORITY
MIN_PRIORITY
让步
yield()
后台(daemon)线程
在后台提供通用服务
不是程序中不可或缺的部分
所有非后台线程结束后,会杀死进程的所有后台线程
setDaemon()
从任务中产生返回值
Runnable不返回任何值
实现Callable接口
call()
ExecutorService.submit()调用
Future对象
共享受限资源
不正确地访问资源
EvenChecker
消费者任务
IntGenerator
EvenGenerator
解决共享资源竞争
why
你永远都不知道一个线程何时在运行
对资源加锁
序列化访问共享资源
互斥量-mutex
synchronized
流程
检查锁是否可用
获取锁
执行代码
释放锁
特定对象
所有方法共享一个锁
每个类
syn static 方法共享
一个任务可以多次获得对象的锁
同步控制EvenGenerator
显式的Lock对象
代码缺乏优雅性
更加灵活
更细粒度的控制
原子性与易变性
原子性
原子操作不能被线程调度机制中断
应用中的可视性
对volatile域修改
所有读操作能立刻看到修改
long和double
两个分离的32位操作
字撕裂
volatile
告诉编译器,不要执行任何读取和写入操作的优化
读取和写入直接针对内存,不被缓存
反例
原子类
AtomicInteger
AtomicLong
AtomicReference
compareAndSet(exp, update)
临界区
同步方法内部的部分代码,不是整个方法
synchronized指定某个对象,锁用来对花括号内的代码同步
(互斥量是同步整个方法)
ThreadLocal
根除对变量的共享
为相同变量的不同线程,创建不同存储
状态↔线程
代码
package Concurrency;<br><br>import java.util.Random;<br>import java.util.concurrent.ExecutorService;<br>import java.util.concurrent.Executors;<br>import java.util.concurrent.TimeUnit;<br><br>public class ThreadLocalVariableHolder {<br> private static ThreadLocal<<Integer> value = <br> new ThreadLocal<<Integer>() {...
终结任务
在阻塞时终结
线程状态
new 新建
Runnable 就绪
Blocked 阻塞
有某个条件阻止线程运行
调度器忽略线程
Dead 死亡
进入阻塞状态
调用sleep()
调用wait()线程挂起
等待某个输入/输出完成
试图在某对象调用同步方法,但对象锁不可用
中断
interrupt()
Executor-shutdownNow()
Executor.submit()返回Future,可调用cancel()
线程间的协作
概述
互斥-解决资源共享问题
协作-多个任务一起工作,解决某个问题
任务之间的握手
wait()和notifyAll()
wait()
等待某个条件发生变化,这个变化由另一任务实现
挂起线程,对象上的锁释放
sleep()和yield()没有释放锁!
将任务挂起,只有在notify()或notifyAll()才被唤醒
notify()
通知对象x
众多等待同一个锁的任务,只有一个被唤醒
错失的信号
死锁
生产者与消费者
Chef
生产者
WaitPerson
消费者
Meal
Restaurant
生产者-消费者与队列
wait()和notifyAll()是低级的任务操作,每次交互都握手
更高的抽象级别-同步队列
BlockingQueue
同一时刻只允许一个任务插入或删除元素
任务间使用管道输入/输出
PipedWriter
PipedReader
死锁
哲学家就餐
5个人,5根筷子,每个人2根筷子才能吃饭,但是一人只拿了1根
Chopstaicks
Philosopher
DeadlockingDining
死锁条件
互斥条件
任务的资源至少有一个是不能共享的(筷子)
持有资源
一个任务持有一个资源,等待另一个资源
资源不能被任务抢占
循环等待
新类库中的构件
CountDownLatch
同步一个或多个任务,强制它们等待由其他任务执行的一组操作
CyclicBarrier
一组任务并行执行,在进行下一个步骤前等待,直至所有任务都完成
所有的并行任务在栅栏处列队,一致地向前移动
DelayQueue
无界的BlockingQueue,放置实现了Delayed的接口对象
对象只能在到期时才能从队列取走
PriorityBlockingQueue
优先级队列,具有可阻塞的读取操作
Exchanger
两个任务交换对象的栅栏
性能调优
免锁容器
原理
对容器的修改可以与读取操作同时发生,只要读取者只能看到完成修改的结果
修改在容器数据结果的副本执行,在修改过程中不可视
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentHashMap
ConcurrentLinkedQueue
乐观加锁
保持数据未锁定状态
ReadWriteLock
优化不频繁写入,但多个任务经常读取的数据结构
如果写锁被持有,任何读取者都不能访问
总结
线程好处
轻量级的执行上下文切换(大约100条指令)
进程需要上千条指令,并改变所有内存空间
而线程只改变程序的执行序列和局部变量
多线程缺点
等待共享资源时,性能↓
处理线程,额外CPU
糟糕的程序设计,导致不必要的复杂度
病态行为:竞争、死锁
不同平台导致的不一致性
第4章 控制执行流程
恰好出现在迭代语句前
continue
继续当前的下一次循环
break
中断当前循环
continue label
继续循环→label处
break label
中断循环→label处
第5章 初始化和清理
用构造器确保初始化
作用
确保每个对象初始化
调用构造器,是编译器的责任
没有返回值
不是返回值为void
this关键字
问题
a.peel(1), b.peel(2)
如何知道是a还是b调用的peel方法?
答案
作为第一个参数→peel()
this-所操作对象的引用
类似于Banana.peel(a, 1)
清理:终结处理和垃圾回收
“特殊”内存
GC仅负责new出来的对象
“本地方法”分配的内存,GC无法回收
finalize()
GC前,调用finalize()
GC,回收对象内存
说明
对象可能不被垃圾回收
垃圾回收只与内存有关
绝对不能直接调用finalize()
对象的创建过程
首次创建Dog对象、访问Dog静态方法,Java解释器定位Dog.class
载入Dog.class,静态初始化
new Dog()时,在堆上分配空间
存储空间清零
基本类型→默认值
引用→null
执行字段定义处的初始化动作
执行构造器
初始化
静态初始化
static{}
首次加载类时执行(即使未生成类对象)
非静态初始化
{}
生成对象时执行,匿名内部类的初始化
构造器(最后执行)
枚举类型
enum类→编译器行为
特性
toString()
ordinal()
特定enum常量的声明顺序
values()
按顺序生成数组
第6章 访问控制权限
为什么控制访问权限?
1.使用户不触碰不该触碰的部分
2.更改内部实现,不影响客户端程序员
访问权限关键字
public
protected
继承的类+同包的类
default
同包的类
private
类的访问权限
可以
public
default
不可以(特例:内部类)
private
protected
第7章 复用类
如何复用?
组合
新类中,产生现有类的对象
继承
按照现有类型,进行复用
调用导出类,先加载基类
@Override
确保覆盖,而非重载
代理
继承和组合的中庸之道
成员对象→构造的类中(组合)
在新类中暴露成员对象的所有方法(继承)
在组合与继承之间选择
组合
显式:在新类中放置子对象
复用具体实现,而非接口
继承
隐式:在新类中放置子对象
新类→基类,复用接口
向上转型
新类是现有类的一种类型
类接口可能丢失方法
final关键字
数据
基本类型
引用
引用所指向的对象恒定不变
指向对象的内容,可以更改
参数
无法改变参数所指向的对象
方法
防止继承类覆盖
private方法隐式地为final的
无法获取→无法覆盖
类
无法被继承
Java的final类
基本类型的包装类
字符串
String
StringBuilder
StringBuffer
数学
Math
StrictMath
系统
System
Class
第8章 多态
对比
多态
分离:做什么↔怎么做,消除类型间的耦合关系
封装
合并:特征↔行为,创建新的数据类型
实现隐藏
分离:接口↔实现,将细节私有化
问题
基类的引用,如何找到继承类的方法?
答案
编译器不知道对象的类型
运行时判断对象的类型,找到正确的方法体
准则
继承:表达行为(方法)间的差异
组合:状态(对象)上的变化
第9章 接口
关系
普通类→抽象类→接口
抽象类和抽象方法
抽象方法
仅有声明,没有方法体
abstract void f()
抽象类
包含抽象方法的类
编译器阻止实例化
可以不包含抽象方法
阻止创建实例
重构工具
公共方法→继承层次向上移动
接口
含义
完全抽象的类
没有任何方法体
域
隐式:static, final
Java 5前,创建常量组的工具(enum)
不能是“空final”
可以被非常量表达式初始化
所有实现了特定接口的类,看起来都像这样
类与类之间的协议
作用
完全解耦
“忽略”继承层次
实现“多重继承”
接口的组合
为什么使用接口?
1.能向上转型为多个基类型
2.防止创建该类的对象
接口与工厂
工厂方法
工厂对象→创建方法
生成接口的某个实现的对象
好处
代码完全与接口的实现分离
透明地将某个实现,替换成另一个实现
第10章 内部类
private内部类
完全阻止依赖于类型的编码
完全隐藏了实现细节
无法访问不属于公共接口的方法
在方法和作用域内的内部类
为什么需要?
实现接口,创建并返回引用
创建类,不希望类公共可用
作用域和普通变量一样
匿名内部类
说明
返回值的生成,表示返回值的类的定义结合在一起!
通过new表达式,自动向上转型为接口的引用
类是匿名的,没有名字
构造器
无参
有参
特点
扩展类or实现接口,不能两者兼备
只能实现一个接口
工厂方法
使用匿名内部类
嵌套类
说明
static 内部类对象×外围类对象
不能从嵌套类的对象,访问非静态的外围类对象
接口内部的类
嵌套类→接口的一部分
接口中的任何东西,都是public和static的
好处
创建公共代码,被所有不同实现共用
为什么需要内部类
入口
内部类对象→访问外围类对象的所有成员
内部类→进入外围类的窗口
多重继承
每个内部类,独立继承一个(接口的)实现
外围类继承层次,对内部类无影响
内部类允许继承多个非接口类型
闭包与回调
回调
对象携带信息,在某一时刻调用初始对象
控制框架
图形用户接口 GUI
事件驱动系统
第11章 持有对象
容器
用途
保存对象
编译期×错误类型→容器
Collection
说明
独立元素的序列
槽内只有一个元素
分类
List
ArrayList
按照插入顺序
√随机访问元素
×中间插入和移除元素
LinkedList
按照插入顺序
√中间插入和移除元素
×随机访问元素
Stack
后进先出 LIFO
Set
元素不能重复
HashSet
散列函数→查询速度快
TreeSet
红黑树→排序
Queue
先进先出 FIFO→并发编程
PriorityQueue
Map
映射表:“键值对”对象
槽内有两个对象:键和与之关联的值
迭代器
统一了对容器的访问方式
只能单向移动
foreach隐形包括迭代器
第二章 一切都会对象
用引用操控对象
遥控器(引用)-->电视机(对象)
必须由你创建所有的对象
存储地点
寄存器
处理器的寄存器--速度最快
不能直接控制
堆栈
通用RAM中
java对象引用
堆
通用的内存池
Java对象
常量存储
程序代码内部
ROM(只读存储器)
非RAM存储
流对象
持久化对象
特例
基本类型
特例:基本类型
boolean
char
byte
shor
int
long
float
double
void
高精度数字
BigInteger
BigDecimal
Java中的数组
自动初始化
范围检查
少量内存开销
运行时下标检查
创建新的类型:类
类成员的基本数据类型初始化
非类字段 -->不初始化
永远不需要销毁对象
第13章 字符串
字符串
String
对象不可变
StringBuilder
非线程安全,可变
StringBuffer
线程安全
格式化输出
Formatter
正则表达式
Java
\\d
\\\\
一个\
其他语言
\d
第14章 类型信息
类型信息
Class对象→JVM类加载器
常用方法
printInfo()
全限定类名
getInterfaces()
包含的接口
getSuperclass()
直接基类
newInstance()
创建类
必须有默认构造器
初始化
对静态方法或非常数静态域的首次引用
static final 不初始化
构造器隐式为静态的
泛化的Class引用
Class
类型判断
x instanceof Integer
RTTI
含义
RunTime Type Info
运行时,识别对象的类型(多态)
编译时打开和检查.class文件
好处
代码只操纵基类的引用
方便扩展程序
反射
public class RT {<br> public static int a = 10;<br> <br> public void say(int a, String s) {<br> System.out.println(a);<br> System.out.println(s);<br> }<br> <br> public void run() {<br> System.out.println("Hello, run()");...
运行时加载类
磁盘中的文件
网络中的一串字节
java.lang.reflect
Field
Method
invoke调用
Constructor
动态代理
中间人→额外的操作
Java的动态代理
@Override<br> public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br> return null;<br> }
动态创建代理
动态处理代理方法的调用
所有调用→单一的调用处理器
代码耦合度,超过你的期望
第15章 泛型
public class HelloWorld {<br> public <<T> void f(T x) {<br> System.out.println(x.getClass().getName());<br> }<br> <br> public static void main(String[] args) {<br> HelloWorld helloWorld = new HelloWorld();<br> helloWorld.f("");<br> helloWorld.f(4);<br> helloWorld.f(4.0);...
引入原因
多态
方法的参数是接口
但是必须满足特定的接口
泛型
更通用→某种不确定的类型(接口)
参数化类型(容器类)
泛型
简单泛型
指定容器要持有什么类型
编译器→保证类型的正确性
元组类库
一次方法调用,返回多个对象
一个对象→持有多个对象
泛型接口
生成器,创建对象的类
泛型方法
泛型参数列表→返回值前
尽量使用泛型方法
擦除
在泛型代码内部,无法获得任何有关泛型参数类型的信息
泛型→具体类型信息→被擦除
边界
泛型的参数类型→设置限制条件
<T extends HasF>
限制为HasF的类型子集
<? super T>
超类型通配符(参数是下界)
某个特定类的任何基类
<?>
无界通配符
第16章 数组
为什么特殊?
效率
简单的线性序列
存储和随机访问对象引用序列
效率最高
类型
保存基本类型
泛型之前的容器不能
优先使用容器
更多的功能
编译期类型检查
效率已经不是问题
Arrays
fill()
填充各个位置
System.arraycopy()
复制数组
比for循环快很多
equals()
比较整个数组
元素个数
对应位置的元素
sort()
排序算法
基本类型
快速排序
引用类型
稳定归并排序
对象比较的方式
java.lang.Comparable接口
编写自己的Comparator
比较
当前对象<参数
负值
当前对=参数
0
当前对象>参数
正值
binarySearch()
排序数组→快速查找
第17章 容器深入研究
填充容器
Collections.nCopies()
Collections.addAll()
Set和存储顺序
Set
每个元素—唯一
元素必须定义equals()
HashSet
元素必须定义hashCode()
TreeSet
保持次序的set,底层为树结构
元素必须实现Comparable接口
方法
first()
返回容器的第一个元素
last()
返回容器的最末一个元素
subSet(from, to)
Set的子集
headSet(to)
<to的Set子集
tailSet(from)
≥from的Set子集
LinkedHashSet
内部使用链表维护插入的次序
元素必须定义hashCode()
理解Map
实现
HashMap
构造器(调整容器性能)
容量
负载因子
TreeMap
基于红黑树的实现
方法
firstKey()
lastKey()
subMap()
fromKey()
headMap()
tailMap()
LinkedHashMap
取得顺序是插入顺序
WeakHashMap
“弱键”,允许释放映射所指向的对象
如果映射外没有引用指向键,则键可以被GC
ConcurrentHashMap
线程安全
不涉及同步加锁
IdentityHashMap
性能
散列码
相对唯一,代表对象的int值
将对象的某些信息转换而成
散列Map,必须实现
equals()和hashCode()
覆盖equals(),总是同时覆盖hashCode()
hashCode()不需要返回唯一的标识码
equals()方法必须严格判断两个对象是否相同
散列与散列码
Object
hashCode()
使用对象的地址计算散列码
equals()
比较对象的地址
equals()
自反性
x.equals(x)=true
对称性
y.equals(x)=true→x.equals(y)=true
传递性
x.equals(y)=true,y.equals(z)=true→x.equals(z)=true
一致性
无论比较对少次,结果都是一样的
x!=null→x.equals(null)=false
理解hashCode()
目的
用一个对象→查找另一个对象
键对象→生成数字(散列码)→数组下标
bucket:实际散列表的数组命名
冲突
equals()方法→线性查询
put()
针对键hashCode(),转换取模
数组的对应位置
null
创建新的LinkedList
非null
list是否有相同元素
有→替换value
没有→添加到list末尾
get()
同put()
覆盖hashCode()
why?
无论何时,对同一个对象调用hashCode()→相同值
hashCode()→处理→桶位下标
how?
不能依赖易变的数据
数据变化→不同散列码
不能依赖具有唯一性的对象信息(this)
Apache库自动生成
HashMap性能因子
容量
桶位数
初始容量
创建时拥有的桶位数
尺寸
当前存储的项数
负载因子
尺寸/容量
空表
0
半满表
0.5
>负载因子,容器自动增加容量,再散列
构造器可以指定,默认0.75
同步控制
自动同步整个容器
synchronizedList()
快速报错
防止多进程同时修改同一容器
持有引用
引用
SoftReference
内存敏感的高速缓存
WeakReference
规范映射,不影响GC回收
对象的实例可以在程序多处同时使用,节省空间
PhantomReference
调度回收前的清理工作
WeakHashMap
保存WeakReference
value只保存一份实例→节省存储空间
Java 1.0/1.1 的容器
Vector
Hashtable
Stack
BitSet
第18章 Java I/O系统
概述
源端-接收端
文件
控制台
网络连接
通信方式
顺序
随机存取
缓冲
二进制
按字符
按行
按字
Preferences
key-value数据集合
基本类型
字符串
单个字符串长度8K
应用
存储和读取用户的偏好
程序配置项的设置
数据存储位置
不是本地文件
使用合适的系统资源
Windows的注册表
输入和输出
流
有能力产出数据的数据源对象
有能力接收数据的接收端对象
Java
输入
InputStream或Reader派生
read()
输出
OutputStream或Writer派生
write()
叠合多个对象→期望功能
InputStream
作用
表示从不同数据源产生输入的类
途径
字节数组
String对象
文件
管道
Internet连接
类型
ByteArrayInputStream
内存的缓冲区
StringBufferInputStream
String
FileInputStream
文件读取信息
PipedInputStream
SequenceInputStream
两个或多个InputStream合并为单一
FilterInputStream
抽象类
OutputStream
作用
输出所要去往的目标
目标
字节数组
文件
管道
类型
ByteArrayOutputStream
内存创建缓冲区
所有送往“流”的数据,都放于此
FileOutputStream
信息写至文件
PipedOutputStream
FilterOutputStream
抽象类
添加属性和接口
FilterInputStream从InputStream读取数据
DataInputStream
BufferedInputStream
LineNumberInputStream
PushbackInputStream
FilterOutputStream向OutputStream写入
DataOutputStream
PrintStream
格式化输出
BufferedOutputStream
Reader和Writer
InputStream和OutputStream
面向字节
8位,byte
Reader和Writer
面向字符
兼容Unicode
信息的来源和去处
InputStream
Reader
适配器
InputStreamReader
OutputStream
Writer
适配器
OutputStreamWriter
FileInputStream
FileReader
FileOutputStream
FileWriter
ByteArrayInputStream
CharArrayReader
ByteArrayOutputStream
CharArrayWriter
PipedInputStream
PipedReader
PipedOutputStream
PipedWriter
File类
表示
特定文件的名称
一个目录下的一组文件的名称
标准I/O
标准输入
System.in
未加工的InputStream
标准输出
System.out
printStream对象
标准错误
System.err
printStream对象
进程控制
Java内部→其他操作系统程序
OSExecute.command()
传递command字符串
新I/O
JDK 1.4
速度提高
通道、缓冲器
修改类
FileInputStream
FileOutputStream
RandomAccessFile
压缩
属于InputStream和OutputStream继承层次
压缩类库按字节方式,不是字符方式
Java档案文件
JAR
Java ARchive
跨平台
一组文件→单个压缩文件
压缩,传输时间短
向服务器发一次请求
对象序列化
意义
创建对象,程序终止时,保存状态
自动弥补操作系统的差异
方法
实现Serializable接口
对象→字节序列
字节序列→原来的对象
轻量级持久化
对象必须显式序列化
显式反序列化
支持特性
远程方法调用RMI
存活于其他计算机的对象
像存活于本机一样
Java Beans
配置状态信息
方法
序列化
创建OutputStream对象
封装在ObjectOutputStream对象中
调用writeObject()即可对象序列化
反序列化
将InputStream封装在ObjectInputStream内
调用readObject()
transient关键字
特定子对象,不想Java序列化保存
逐个字段关闭序列化
只能和Serializable对象配合使用
XML
对象序列化限制
仅是Java的解决方案
只有Java程序能反序列化这种对象
优点
跨平台
跨语言
I/O流的典型使用
缓冲输入文件
基本的文件输出
第19章 枚举类型
简介
具名的值的有限集合→新的类型
作为常规的程序组件使用
基本enum特性
values()
enum实例的数组
ordinal()
enum实例在声明时的次序
从0开始
name()
实例声明的名字
向enum添加新方法
定义方法时,enum实例序列最后要加分号
enum不能被继承,剩下就像普通类
使用接口组织枚举
在接口内部,创建实现该接口的枚举→枚举分组
常量相关的方法
为enum实例编写方法→不同的行为
第20章 注解
概述
元数据、源代码文件结合在一起
有关程序的额外信息
注解处理器
读取注解的工具
内置注解
@Override
当前方法覆盖超类的方法
@Deprecated
使用该元素,会发出警告
@SuppressWarnings
关闭不当的编译期警告信息
元注解
专门负责创建新的注解
@Target
表示注解可以用在什么地方
ElementType
CONSTRUCTOR
构造器声明
FIELD
域声明
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注解类型)或enum声明
优点
减轻编写“样板”代码的负担
更加干净易读的代码
编译期类型检查
@Documented
注解包含在Javadoc中
@Inherited
允许子类继承父类中的注解
提取注解
已知实现类
Class:类定义
Constructor:构造器定义
Field:累的成员变量定义
Method:类的方法定义
Package:类的包定义
方法
getAnnotation:返回元素上指定类型的注解,如果该类型注解不存在,则返回null。
getAnnotations():返回该程序元素上存在的所有注解。
isAnnotationPresent:判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
getDeclaredAnnotations():返回存在于此元素的所有注解
@Rectetion
在什么级别保存注解信息
RetentionPolicy
SOURCE
注解被编译期丢弃
CLASS
注解在class文件中可用,但会被VM丢弃
RUNTIME
VM运行期也保留注解
可用通过反射机制读取注解信息
第12章 异常
异常处理的优点之一,就是它使得你可以在某处集中精力处理你要解决的问题,而在另一处处理你编写代码产生的错误。<br><br>Java坚定地强调将所有的错误都以异常形式报告的这一事实,正是它远超过注入C++这类语言的长处之一。
发现错误
编译阶段
运行时
好处
提供一致的错误报告模型
节省代码
正常逻辑↔错误逻辑
Throwable
Error
JVM报告系统错误
Exception
编译期检查
RuntimeException
运行时异常
可忽略,防止代码臃肿
try-catch-finally
catch
仅处理匹配的catch子句
派生类对象,可以匹配基类
finally
子句总会执行
即使try中有return!
基本异常
构造器
默认
字符串参数
用名称代表发生的问题
根类
Throwable
printStackTrace()
从方法调用处→异常抛出处的方法调用序列
标准错误流
栈底:第一个方法调用