Java高级
2018-05-15 17:37:44 67 举报
AI智能生成
Java高级编程
作者其他创作
大纲/内容
异常处理
好处
降低错误处理的复杂度
节省代码
提供一致的错误报告模型
Throwable
Error
JVM报告系统错误
Exception
编译期检查
RuntimeException
运行时异常
可忽略,防止代码臃肿
创建自定义异常
Class SimpleException extends Exception{}
try-catch-finally
catch
仅处理匹配的catch子句
派生类对象,可以匹配基类
finally
子句总会执行
即使try中有return!
清理的资源
已经打开的文件或网络连接
在屏幕上画的图形
甚至是外部世界的某个开关
异常说明
使用附加的关键字throws
void f() throws TooBig,TooSmall,DivZero{}
捕获异常
栈轨迹
printStackTrace()方法
重新抛出异常
子主题
异常链
使用initCase()方法而不是构造器
异常使用指南
在恰当的级别处理问题
解决问题并且重新调用产生异常的方法
进行少许修补,然后绕过异常发生的地方继续执行
用别的数据进行计算,以替代方法预计会返回的值
把当前运行环境下能做的事情尽量做完,然后把相同的异常重抛到更高层
把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层
终止程序
进行简化
让类库和程序更安全
泛型
概念
告诉编译器想要使用什么类型,然后编译器帮你处理一切细节
泛型类
规则
泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开
一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符
因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型
使用泛型类时,必须在创建对象的时候指定类型参数的值
例子
public class Box <T> {}
泛型方法
规则
所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前。
使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型,这称为“参数类型推断”
每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)。
例子
原则
无论何时,只要你能做到,就应该尽量使用泛型方法
对于一个static的方法而言,无法访问泛型类的类型参数,如果static方法需要使用泛型能力,就必须使其成为泛型方法
擦除
概念
泛型是使用擦除实现的,这样在使用泛型时,具体的类型都被擦除了,所以在泛型代码内部,无法获得任何有关泛型参数类型的信息
规则
泛型不能用于显示地引用运行时类型的操作之中,例如转型、instanceof操作和new表达式
在整个类中的各个地方,类型T都在被替换,但是事实并非如此,无论何时,当你在编写这个类的代码时,必须提醒自己,它只是一个Object
对于在泛型中创建数组,使用Array.newInstance()是推荐的方式
成功创建泛型数组的唯一方式就是创建一个被擦除类型的新数组,然后对其转型
通配符
<?>的作用
<?>可以被认为是一种装饰,它是在声明:“我想用Java的泛型来编写这段代码,我不用原生类型,但是在此情况下,泛型参数可以持任何类型”
问题
任何基本类型都不能作为类型参数
实现参数化接口
转型和警告
重载
基类劫持了接口
自限定类型
类型通配符上限
List如此定义就是通配符泛型值接受Number及其下层子类类型
类型通配符下限
List表示类型只能接受Number及其三层父类类型
价值
可以创建协变参数类型
对缺乏潜在类型机制的补偿
反射
用适配器仿真潜在类型机制
子主题
注解
概念
在代码中添加信息提供了一种形式化的方式
可以在稍后某个时候非常方便地使用这些数据
作用
能够以将由编译器来测试和验证的格式,存储有关程序的额外信息
生成描述符文件,甚至或是新的类定义,并且有助于减轻编写“样本”代码的负担
通过使用注解,可以将元数据保存在Java源码中,并利用annotation API为自己的注解构造处理工具
更加干净易读的代码以及编译器类型检查等
内置注解
@Override
覆盖超类中的方法
@Deprecated
使用该元素,会发出警告
@SuppressWarnings
关闭不当的编译期警告信息
元注解
@Target
表示注解可以用在什么地方
ElementType
CONSTRUCTOR
构造器的声明
FIELD
域声明(包括enum实例)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类,接口(包括注解类型)或enum声明
@Retention
表示需要在什么级别保存该注解信息,可选的RetentionPolicy参数包括
ElementType
SOURCE
注解将被编译器丢弃
CLASS
注解在class文件中可用,但被VM丢弃
RUNTIME
VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
@Documented
将此注解包含在Javadoc中
@Inherited
允许子类继承父类中的注解
注解元素可用的类型
所有的基本类型(int,float,boolean)
String
Class
enum
Annotation
以上类型的数组
提取注解
已知实现类
Class:类定义
Field:累的成员变量定义
Constructor:构造器定义
Method:类的方法定义
Package:类的包定义
方法
getAnnotation:返回元素上指定类型的注解,如果该类型注解不存在,则返回null。
getAnnotations():返回该程序元素上存在的所有注解。
isAnnotationPresent:判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
getDeclaredAnnotations():返回存在于此元素的所有注解
注解处理器
提取注解的工具
字符串
字符串
String
不可变
String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象
StringBuilder
非线程安全,可变
StringBuffer
线程安全
格式化输出
Formatter
正则表达式
Pattern
用static Pattern.compile()方法编译正则表达式,会根据String类型的正则表达式生成一个Pattern对象
Matcher
把想要的检索的字符串传入Pattern对象的matcher()方法,mather()方法会生成一个Matcher对象
集合
collection
List
ArrayList
底层的数据结构采用数组
查询很快,但是增加删除很慢
线程不同步
排列有序,可重复
LinkedList
排列有序,可重复
底层使用双向循环链表数据结构
查询慢,增删快
线程不安全
Vector
排列有序,可重复
底层使用数组
查询快,增删慢
线程安全,效率低
Set
HashSet
排列无序,不可重复
底层使用Hash表实现
存取速度快
内部是HashMap
LinkedHashSet
采用Hash表存储,并用双向链表记录插入顺序
内部使用LinkedHashMap
TreeSet
排列无序,不可重复
底层使用二叉树实现
排序存储
内部使用TreeMap的SortedSet
Queue
在两端出入的List,所以也可以使用数组和链表实现
工具类
Collections、Arrays类
提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作
Comparable
Comparable用作默认的比较方式,实现了该接口的类之间可以相互进行比较,这个对象组成的集合就可以直接通过sort()进行排序了
Comparator接口
Comparator是设计模式中策略模式的一种应用
Map
HashMap
键不可重复,值可重复
底层使用哈希表
线程不安全
允许key为null,value也可以为null
Hashtable
键不可重复,值可重复
底层使用哈希表
线程安全
key,value都不允许为null
TreeMap
键不可重复,值可重复
底层为二叉树
SortedMap接口
进一步提供关于键的总体排序 的 Map
I/O
字节流
InputStream
数据来源
字节数组
String对象
文件
“管道”,工作方式与实际管道相似,即,从一端输入,一端输出
由其它种类的流组成的序列
其它数据源,如Internet连接等
种类
ByteArrayInputStream
允许将内存中的缓冲区当做InputStream使用
StringBufferInputStream
将String转成InputStream
FileInputStream
用于从文件中读取信息
PipedInputStream
产生用于写入相关PipedOutputStream的数据,实现“管道化”的概念
SequenceInputStream
将两个或多个InputStream对象转换成单一的InputStream
FilterInputStream
分类
DataInputStream
与DataOutputStream搭配使用,因此我们可以按照可移植方式从流读取基本数据类型
BufferedInputStream
使用它可以放置每次读取都得进行实际写操作。代表“使用缓冲区”
LineNumberInputStream
跟踪输入流中的行号;可调用getLineNumber()和setLineNumber(int)
PushbackInputStream
具有“能弹出一个字节的缓冲区”,因此可以将读到的最后一个字符回退
OutputStream
数据去向
字节数组
文件
管道
种类
ByteArrayOutputStream
在内存中创建缓冲区。所有送往“流”的数据都要放置在此缓冲区
FileOutputStream
用于将信息写至文件
PipedOutputStream
任何写入其中的信息都会自动作为相关PipedInputStream的输出
FilterOutputStream
分类
DataOutputStream
与DataOutputStream搭配使用,因此可以按照可移植方式向流中写入基本类型数据
PrintStream
用于产生格式化输出。其中DataOutputStream处理数据的存储,PrintStream处理显示
BufferedOutputStream
使用它可以避免每次发送数据时都要进行实际的写操作,代表使用缓冲区,可以调用flush清空缓冲区
字符流
Reader
BufferedReader
LineNumberReader
CharArrayReader
FilterReader
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriter
PipedWriter
StringWriter
PrintWriter
独立类
RandomAccess
实现了DataInput和DataOutput接口
工作方式类似于把DataInputStream和DataOutStream组合起来使用
典型使用方式
缓冲输入文件
从内存输入
格式化的内存输入
基本的文件输出
存储和恢复数据
读写随机访问文件
管道流
枚举
概念
一组具名的值的有限集合创建为一种新的类型
可以作为常规的组件使用
基本enum特性
values方法
遍历enum实例
ordinal方法
每个enum实例在声明时的次序
name方法
返回enum实例声明时的名字,与toString()方法效果相同
将静态导入用于enum
使用static import能够将enum实例的标识带入当前的命名空间,无需再用enum类型修饰enum实例
向enum添加新方法
提供构造器,添加额外信息,然后添加方法,返回这个描述信息
定义自己的方法,必须在enum实例序列的最后添加一个分号
enum不能被继承
必须先定义enum实例
可以覆盖enum的方法
使用接口组织枚举
在接口内部,创建实现该接口的枚举,以此将元素进行分组
对于enum而言,实现接口是使其子类化的唯一办法
使用EnumSet替代标志
通过enum创建一种替代品,以替代传统的基于int"位标志"
优点
它在说明 一个二进制位是否存在时,具有更好的表达能力,并且无需担心性能
EnumSet中的元素必须来自一个enum
使用EnumMap
是一种特殊的Map,它要求其中的键必须来自一个enum
优点
允许程序员改变值对象,而常量相关方法在编译期就被固定了
常量相关方法
为enum实例编写方法→不同的行为
使用
使用enum的职责链
使用enum的状态机
多路分发
使用enum分发
使用常量相关的方法
类型信息
运行时类型信息使得你可以在程序运行时发现和使用类型信息
Class对象
用来创建类的所有的“常规”对象的
常用方法
forName()
取得Class对象的引用的一种方法
printInfo()
全限定类名
getInterfaces()
包含的接口
getSuperclass()
直接基类
getSimpleName()
不包含名的类名
isInterface()
判断某个Class对象是否表示某个接口
newInstance()
实现“虚拟构造器”的一种途径
泛化的Class引用
Class<? extends Integer>
新的转型语法
cast()方法
RTTI
含义
RunTime Type Info
运行时,识别对象的类型(多态)
编译时打开和检查.class文件
好处
代码只操纵基类的引用
方便扩展程序
反射
远程调用
在跨网络的平台上创建和运行对象的能力
java.lang.reflect
Field类
Method类
Constructor类
动态代理
提供额外的或不同的操作,而插入的用来代替“实际”对象的对象
创建动态代理
调用Proxy.newProxyInstance()创建动态代理
Method.invoke()将请求转发给代理对象
空对象
假设所有的对象都是有效的,不必浪费精力去检查null
创建一个标记接口,继承这个标记接口以实现空对象
public interface Null()
数组
特殊性
效率
存储和随机访问对象那个引用序列的方式
简单的线性序列,访问速度快
效率高
类型
保存基本类型的能力
泛型之前的容器不能
优先使用容器
更多的功能
编译器类型检查
效率已经不是问题
Arrays
fill()
用同一个值填充各个位置,而针对对象而言,就是复制同一个引用进行填充
System.arraycopy()
复制数组比用for循环复制快很多
equals()
比较两个数组
sort()
排序算法
基本类型
快速排序
引用类型
稳定归并排序
对象比较的方式
java.lang.Comparable接口
编写自己的Comparator
比较
当前对象<参数
负值
=
0
当前对象>参数
正值
binarySearch()
排序数组→快速查找
0 条评论
下一页