赞
踩
注意:Java 教程是为 JDK 8编写的。本页中描述的示例和实践没有利用后期版本中引入的改进,并且可能使用不再可用的技术。有关 Java SE 9和后续版本中更新的语言特性的摘要,请参阅 Java 语言更改。有关所有 JDK 版本的新特性、增强功能以及已删除或已弃用选项的信息,请参阅 JDK 发布说明。
本文是对官方教程的简单总结,省略了许多示例,阅读中如有疑惑请参阅文章末尾的参考链接查看官方教程。






关于 Java
既是一种编程语言,也是一种平台。
编程语言
java 平台
Java 可以做什么
开发工具
应用程序接口
部署技术
用户界面工具箱
集成库
代码注释
类定义
main 方法
对象
类
继承
接口
包
变量
实例变量(非静态字段)
类变量(静态字段)
局部变量
参数
命名规则
基本数据类型
byte
short
int
long
float
double
boolean
char
除了上面列出的8种基本数据类型之外,Java 编程语言还通过 Java .lang. String 类提供了对字符串的特殊支持。用双引号括住你的字符串会自动创建一个新的 String 对象;例如,String s = "this is a String ";字符串对象是不可变的,这意味着一旦创建,它们的值就不能更改。String类在技术上不是基本数据类型,但考虑到语言给予它的特殊支持,您可能倾向于认为它是基本数据类型。
默认值
字面量
基本类型是内置在语言中的特殊数据类型;它们不是从类中创建的对象。字面量是一个固定值的源代码表示;字面量直接在代码中表示,不需要计算。
整数字面值
浮点字面值
字符与字符串字符值
类字面量
在数字字符中使用下划线字符
数组
声明一个变量引用一个数组
创建、初始化和访问数组
复制数组
数组操作
运算符
优先级
赋值
算数
一元运算符
相等
关系
条件
类型比较
位与位移
表达式,语句和块
控制流程语句
if-then 和 if-then-else 语句
switch 语句
while 和 do-while 语句
for 语句
分支语句
break 语句
continue 语句
return 语句
类
声明类
声明成员变量
分类
访问修饰符
类型
变量名
定义方法
修饰符,返回类型,方法名,参数列表,异常列表,方法体
方法签名:方法名和参数类型
方法命名
重载方法
构造方法
给方法或构造方法传递信息
对象
创建对象
声明,实例化,初始化
声明一个变量来引用一个对象
实例化一个类
使用对象
深入类
方法的返回值
返回时机
返回一个类或接口
this 关键字
访问控制
访问层级
顶级
成员级
类成员
类变量
类方法
常量
初始化字段
静态初始化块
初始化块
使用 final 方法初始化实例变量(用于子类希望重用初始化方法)
嵌套类
使用嵌套类的原因
内部类(非静态)
不可以定义静态成员,可以定义常量
内部类的实例对象存在于外部类的实例中
举例
修饰符
本地类
在块中定义,一般是在方法中
声明
访问外围类的成员
匿名类
和本地类类似,除了没有名字
声明
语法
访问外围作用域中的本地变量
声明与访问匿名类的成员
Lambda 表达式
函数作为方法参数或者说代码作为数据
理想用例
创建搜索匹配某一特性成员的方法
创建更通用的搜索方法
在本地类中指定搜索条件
在匿名类中中指定搜索条件
在 Lambda 表达式中指定搜索条件
使用 Lambda 表达式的标准函数接口
在应用中使用 Lambda 表达式
更广泛的使用泛型
使用接受 Lambda 表达式作为参数的聚合操作
GUI 程序中的 Lambda 表达式
语法
用逗号分隔的形式参数列表,用括号括起来(参数数据类型可省略,如果只有一个参数,可以省略括号)
箭头符号:->
主体
访问外围作用域中本地变量
目标类型
方法所期望的数据类型
只能在 Java 编译器可以确定目标类型的情况下使用lambda 表达式
方法参数
序列化
方法引用
分类
引用静态方法
引用特定对象的实例方法
引用特定类型的任意对象的实例方法
引用构造函数
静态嵌套类
影子
序列化
使用时机
本地类
匿名类
Lambda 表达式
嵌套类
枚举类型
元数据的一种形式,提供关于程序的数据,而这些数据不是程序本身的一部分。注释对它们所注释的代码的操作没有直接影响。
应用
基础
注释的格式
java8 支持重复注释
注释可以使用的地方
声明:类、字段、方法和其他程序元素的声明。在声明上使用时,根据约定,每个注释通常出现在自己的行上。
从 java8 开始,注释也可以应用于类型的使用
声明一个注解类型
预定义注解类型
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
适用于其他注解的注解
类型注解可插拔类型系统
重复注解
检索注解
设计考虑
基数性
位置
一种引用类型,类似于类,只能包含常量、方法签名、默认方法、静态方法和嵌套类型。方法体只存在于默认方法和静态方法中。接口不能被实例化——它们只能由类实现或由其他接口扩展
接口作为 api
定义接口
public,interface,extends
接口体
实现接口
以类型的方式使用接口
默认方法
默认方法使您能够向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性。
扩展包含默认方法的接口
静态方法
将默认方法集成到现有库中
定义
除了 Object,它没有超类,每个类都有且只有一个直接超类(单继承)。在没有任何其他显式超类的情况下,每个类都隐式地是Object 的子类。
子类从父类继承所有成员(字段、方法和嵌套类)。构造函数不是成员,因此不能由子类继承,但是父类的构造函数可以从子类调用。
Java 平台类层次结构
在子类中可以做什么
超类的私有成员
转换对象
状态、实现和类型的多重继承
覆盖和隐藏方法
实例方法
静态方法
被调用的被重写实例方法的版本是子类中的版本。
被调用的隐藏静态方法的版本取决于它是从父类还是子类调用的。
接口方法
覆盖方法的访问说明符可以允许比被覆盖方法更多的访问,但不能更少。
重载
多态性
隐藏字段
super 关键字
访问超类成员
子类的构造函数
Object 类
protected Object clone() throws CloneNotSupportedException
public boolean equals(Object obj)
protected void finalize() throws Throwable
public final Class getClass()
public int hashCode()
public String toString()
线程同步相关
编写 Final 类和方法
抽象类和方法
数字
Number 类
所有数字包装类都是 Number 类的子类
使用 Number 对象的情况
Number 子类需要实现的方法
数字打印输出格式化
printf 和 format 方法
DecimalFormat 类
Math 类
静态导入
常量
基本方法
绝对值
四舍五入
上界,下界
最小,最大
指数,对数
三角函数
随机数
Character 类
不可变
方法
转义字符
字符串
创建 String
字符串长度
字符串连接
创建格式字符串
数字和字符串之间的转换
字符串转数字
数字转字符串
操作字符串中的字符
获取
charAt()
substring()
其他方法
搜索
替换
比较与部分比较
StringBuilder 类
与String对象类似,只是它们可以被修改。在内部,这些对象被视为包含字符序列的变长数组。在任何时候,序列的长度和内容都可以通过方法调用来更改。
长度和容量
操作
自动装箱与拆箱
为什么使用泛型
泛型类型
是通过类型参数化的泛型类或接口。
类型参数命名约定
调用和实例化泛型类型
菱形
多种类型参数
参数化类型
粗类型
是没有任何类型参数的泛型类或接口的名称,非泛型类或接口类型不是粗类型。
为了向后兼容,允许将参数化类型赋值给粗类型
未检查错误消息
泛型方法
泛型方法是引入自己的类型参数的方法。这类似于声明泛型类型,但类型参数的作用域仅限于声明它的方法。允许使用静态和非静态泛型方法,以及泛型类构造函数。
语法
类型推断
受限类型参数
上界:extends
多个边界:&
泛型方法和有界类型参数
泛型,继承与子类型
类型推断
通配符
上界通配符
无界通配符
?
如果您正在编写一个可以使用 Object 类中提供的功能实现的方法。
当代码在泛型类中使用不依赖类型参数的方法时。
需要注意的是,List<Object> 和 List<?> 是不一样的。您可以将 Object 或 Object 的任何子类型插入到 List\
包是提供访问保护和名称空间管理的相关类型的分组。
创建
命名
使用包成员
组成包的类型称为包成员。
若要从其包外部使用公共包成员,必须执行以下操作之一
另一种不太常见的导入形式允许导入外围类的公共嵌套类。
为了方便起见,Java编译器会自动为每个源文件导入两个完整的包:(1) Java.Lang 包和 (2) 当前包 (当前文件所在的包)
包的层次结构
名称冲突
静态导入语句
管理源码与类文件
什么是异常
Catch 或指定要求
可能引发某些异常的代码必须包含以下任何一种:
三种异常类型
检查异常
错误
运行时异常
错误和运行时异常统称为未检查异常。
绕过 Catch 或指定
捕获和处理异常
try 语句块
catch 语句块
通过在 try 块之后直接提供一个或多个 catch 块,可以将异常处理程序与 try 块关联起来。
每个 catch 块都是一个异常处理程序,用于处理由其参数指示的异常类型。参数类型声明了处理程序可以处理的异常类型,并且必须是继承自 Throwable 类的类名。
异常处理程序可以做的不仅仅是打印错误消息或停止程序。它们可以执行错误恢复,提示用户做出决定,或者使用链式异常将错误传播到更高级别的处理程序
用一个异常处理程序捕获多种类型的异常
finally 语句块
try-with-resources 语句
是一个 try 语句,声明一个或多个资源。资源是程序使用完后必须关闭的对象。try-with-resources 语句确保在语句末尾关闭每个资源。任何实现 java.lang.AutoCloseable 的对象,包括所有实现 java.io.Closeable 的对象。可作为资源使用。
try-with-resources 语句可以像普通的 try 语句一样有catch 和 finally 块。在 try-with-resources 语句中,任何 catch 或 finally 块都在声明的资源被关闭后运行
抑制异常
指定方法抛出的异常
抛出异常
Java 平台提供了大量异常类。所有的类都是 Throwable类的后代,并且都允许程序区分在程序执行期间可能发生的各种类型的异常。
throw 语句
Throwable 类及其子类
Error
Exception
异常链
Throwable 中的方法以及构造函数
访问堆栈跟踪信息
日志 API
创建异常类
何时
选择超类
对于可读的代码,将字符串 Exception 附加到(直接或间接)从 Exception 类继承的所有类的名称后是一个很好的实践。
未检查异常
异常的优点
I/O 流
字节流
程序使用字节流来执行8位字节的输入和输出。
InputStream,OutputStream
使用
关闭
使用时机
字符流
Java 平台使用 Unicode 约定存储字符值。字符流 I/O 自动将这种内部格式转换为本地字符集。
使用字符流代替字节流的程序可以自动适应本地字符集,并为国际化做好准备——所有这些都不需要程序员付出额外的努力。
Reader, Writer
使用
使用字节流的字符流
面向行的 I/O
缓冲流
BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter
刷新
扫描与格式化
编程 I/O 通常涉及到将数据与人们喜欢使用的格式之间转换。
扫描
Scanner 类
将输入分解为标记
翻译单个标记
格式化
PrintWriter,PrintStream
惟一可能需要的 PrintStream 对象是 System.out 和 System.err。当需要创建格式化输出流时,实例化PrintWriter,而不是 PrintStream。
print 和println 方法
format 方法
命令行 I/O
标准流
控制台
数据流
支持基本数据类型值以及 String 值的二进制I/O。
DataInput ,DataOutput
DataInputStream,DataOutputStream
用于货币值的正确类型是 java.math.BigDecimal。不幸的是,BigDecimal 是一种对象类型,因此它不能用于数据流。但是,BigDecimal 将使用对象流。
对象流
大多数(但不是全部)标准类支持其对象的序列化。那些实现标记接口 Serializable 的。
ObjectInput,ObjectOutput
ObjectInputStream,ObjectOutputStream
复杂对象的输出和输入
文件 I/O(NIO.2 特性)
路径
用于分隔目录名的字符(也称为分隔符)是特定于文件系统的: Solaris OS 使用正斜杠(/),Microsoft Windows 使用反斜杠()。
相对与绝对
符号链接(软链接)
Path 类
是 java.nio.file 包的一个主要入口点
Path 对象包含用于构造路径的文件名和目录列表,并用于检查、定位和操作文件。
路径与系统无关。您不能比较来自 Solaris 文件系统的Path,并期望它与来自 Windows 文件系统的 Path 相匹配,即使目录结构相同且两个实例定位相同的相对文件。
创建
检索
移除路径中的冗余
路径转换
toUri
toAbsolutePath
组合路径
在两条路径之间创建路径
比较两种路径
文件操作
Files 类是 java.nio.file 包的另一个主要入口点。
释放系统资源
捕获异常
可变参数
原子操作
方法链
glob
glob 模式被指定为字符串,并与其他字符串(如目录或文件名)进行匹配
getPathMatcher
星号 * 匹配任意数量的字符(包括 none)。
两个星号 ** 类似于 *,但跨越了目录边界。此语法通常用于匹配完整路径。
问号 ? 只能匹配一个字符。
花括号指定子模式的集合。
方括号表示一组单个字符,如果使用连字符(-),则表示一组字符。
所有其他字符都与自己匹配。
要匹配*、?或其他特殊字符,可以使用反斜杠字符\进行转义
链接感知
检查文件或目录
验证文件或目录是否存在
exists(Path, LinkOption…),notExists(Path, LinkOption…)
验证结果
检查文件可访问性
检查两条路径是否指向同一个文件
删除文件或目录
复制文件或目录
copy
如果目标文件存在,复制将失败,除非指定了 REPLACE_EXISTING 选项。
目录可以复制。但是,目录内的文件不会被复制,因此即使原始目录中有文件,新目录也是空的。
复制符号链接时,将复制该链接的目标。如果您想复制链接本身,而不是链接的内容,请指定 NOFOLLOW_LINKS或 REPLACE_EXISTING 选项。
REPLACE_EXISTING,COPY_ATTRIBUTES,NOFOLLOW_LINKS
Files 类还定义了可用于在文件和流之间进行复制的方法。
递归复制
移动文件或目录
管理元数据(文件和文件存储属性)
读,写,创建文件
OpenOptions 参数
小文件常用方法
从文件中读取所有字节或行
将所有字节或行写入文件
文本文件的缓冲I/O方法
file 包支持通道 I/O,它可以在缓冲区中移动数据,绕过一些可能会导致流 I/O 瓶颈的层。
使用缓冲流I/O读取文件
使用缓冲流I/O写入文件
可与 java.io APIs 互操作的无缓冲流方法
使用流I/O读取文件
使用流I/O创建和写入文件
Channels 与 ByteBuffers 的方法
使用通道I/O读写文件
创建常规文件和临时文件的方法
创建文件
创建临时文件
随机访问文件
SeekableByteChannel
创建,读取目录
列出文件系统的根目录
创建目录
创建临时目录
列出目录的内容
使用 Globbing 过滤目录列表
编写自己的目录过滤器
链接,符号和其他
硬链接
创建符号链接
创建硬链接
检测符号链接
发现链路的目标
遍历文件树
FileVisitor 接口
启动文件遍历
创建 FileVisitor 时的注意事项
控制流
查找文件
查看目录的更改
Watch Service API
Watch Service 简介
低级,允许自定义。
实现步骤
watchkey 是线程安全的,可以与 java.nio.concurrent 包一起使用。您可以专门为这项工作提供一个线程池。
尝试
创建监视服务并注册事件
WatchService watcher = FileSystems.getDefault().newWatchService();
Watchable 接口
StandardWatchEventKinds
处理事件
获取一个 watch key
处理顺序
watch key 的状态
检索文件名
API 使用时机
其他有用的方法
确定MIME类型
默认文件系统
路径字符串分隔符
文件系统的文件存储
遗留 File I/O 代码
与遗留代码的互操作性
将java.io.File 功能映射到 java.nio.file
进程与线程
线程对象
每个线程都与 thread 类的一个实例相关联。
基本策略
定义和启动一个线程
线程中运行的代码
调用 Thread.start 启动一个新线程
使用 Sleep 暂停执行
中断
中断是对线程的一个指示,它应该停止正在做的事情并做其他事情。由程序员决定线程如何响应中断,但是线程终止是很常见的。
线程通过调用将要中断的线程的 thread 对象的 interrupt 来发送中断。为了使中断机制正确工作,被中断的线程必须支持自己的中断。
支持中断
取决于它当前正在做什么。
许多抛出 InterruptedException 的方法(如 sleep)被设计为取消当前操作,并在接收到中断时立即返回。
如果线程运行很长时间而没有调用抛出InterruptedException 的方法,该怎么办?然后它必须周期性地调用 Thread.interrupted,如果接收到中断则返回 true。
中断状态标志
加入
join()
示例
同步
线程干扰
内存一致性错误
当不同线程对应该是相同数据出现视图不一致时,就会发生内存一致性错误。
程序员不需要详细了解这些原因。我们所需要的只是一种避免它们的策略。
happens-before 关系
具有 happens-before 关系的行为
同步方法
内在锁与同步
同步是围绕一个称为内在锁或监视器锁的内部实体构建的。(API规范通常将此实体简单地称为“监视器”)
内在锁在同步方面都发挥作用
每个对象都有一个与之相关的内在锁。
按照惯例,需要独占和一致访问对象字段的线程必须在访问对象字段之前获得对象的内在锁,然后在使用完对象字段时释放内在锁。线程在获得锁和释放锁之间拥有内在锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程在试图获取锁时将阻塞。
当线程释放一个内在锁时,在该操作和后续获得的任何相同锁之间建立 happens-before 关系。
同步方法中的锁
同步语句
可重入同步
原子访问
一个有效地同时发生的事件
原子的动作不可能中途停止:它要么完全发生,要么根本不发生。在操作完成之前,原子操作的副作用是不可见的。
可以指定为原子的行为
活跃度
并发应用程序及时执行的能力被称为它的活跃度
死锁
饥饿与活锁
保护块
不可变对象
如果一个对象的状态在被构造后不能改变,它被认为是不可变的。
不可变对象在并发应用程序中特别有用。由于它们不能改变状态,因此不会被线程干扰破坏或处于不一致的状态。
同步类示例
定义不可变对象的策略
下面的规则定义了一个创建不可变对象的简单策略。并不是所有记录为“不可变”的类都遵循这些规则。这并不一定意味着这些类的创建者很草率——他们可能有很好的理由相信他们类的实例在构造之后永远不会改变。然而,这种策略需要复杂的分析,不适合初学者。
不要提供“setter”方法——修改字段或字段引用的对象的方法。
将所有字段设置为 final 和 private。
不允许子类重写方法。最简单的方法是将类声明为 final。更复杂的方法是将构造函数设为私有,并在工厂方法中构造实例。
如果实例字段包含对可变对象的引用,则不允许更改这些对象
高级并发对象
java.util.concurrent
锁对象
执行器
在大型应用程序中,将线程管理和创建与应用程序的其余部分分离是有意义的。封装这些函数的对象称为执行器。
执行器接口
Executor
ExecutorService
ScheduledExecutorService
线程池
大多数执行器实现使用线程池,线程池由工作线程组成。
这种线程与它执行的 Runnable 和 Callable 任务分开存在,通常用于执行多个任务。
使用工作线程可以最小化由于线程创建造成的开销。
固定线程池
总是有指定数量的线程在运行
如果一个线程在仍在使用时以某种方式终止,则会自动用一个新线程替换它。
任务通过内部队列提交到池中,当活动任务多于线程时,内部队列就会保存额外的任务。
优点
Executors
额外的选项
Fork/Join
fork/join 框架是 ExecutorService 接口的实现,它可以帮助您利用多个处理器
它是为可以递归分解为更小块的工作而设计的。目标是使用所有可用的处理能力来增强应用程序的性能。
与任何 ExecutorService 实现一样,fork/join 框架将任务分配给线程池中的工作线程。fork/join 框架是独特的,因为它使用了工作窃取算法。当工作线程工作完时,可以从其他线程那里窃取任务。
ForkJoinPool 类
基本使用
帮助理解
标准实现
并发集合
BlockingQueue
ConcurrentMap
ConcurrentNavigableMap
原子变量
并发随机数
参考资料
应用程序在平台环境中运行,平台环境由底层操作系统、Java虚拟机、类库和应用程序启动时提供的各种配置数据定义。
配置工具
帮助应用程序访问其启动上下文的配置实用程序。
属性
属性是作为键/值对管理的配置值。在每对中,键和值都是 String 值。键标识并用于检索值,就像变量名用于检索变量的值一样。
java.util.Properties 类
管理属性
方法
扩展了 java.util.Hashtable
System 类维护一个 Properties 对象,该对象定义当前工作环境的配置。
应用程序生命周期中的属性
Starting Up
Running
Exiting
设置属性对象
保存属性
获取属性信息
设置属性
上面描述的一些方法是在 Hashtable 中定义的,因此接受 String 以外的键和值参数类型。始终使用字符串作为键和值,即使该方法允许其他类型。也不要在属性对象上调用 Hashtable.set 或 Hastable.setAll,总是使用Properties.setProperty。
命令行参数
Java应用程序可以从命令行接受任意数量的参数。这允许用户在启动应用程序时指定配置信息。
用户在调用应用程序时输入命令行参数,并在要运行的类名之后指定它们。
响应命令行参数
解析数值型命令行参数
环境变量
许多操作系统使用环境变量将配置信息传递给应用程序。与Java平台中的属性一样,环境变量也是键/值对,其中键和值都是字符串。设置和使用环境变量的约定因操作系统和命令行解释器的不同而不同。
查询环境变量
向新进程传递环境变量
平台依赖问题
在不同系统上实现环境变量的方式之间存在许多微妙的差异
环境变量的使用方式也各不相同。
其他
Preferences API
部署在 JAR 存档中的应用程序使用 manifest 来描述存档的内容。
Java Web Start 应用程序的配置包含在 JNLP 文件中。
Java Plug-in applet 的配置部分由用于将 applet 嵌入web 页面的 HTML 标记决定。
Serviceloader 类提供了一个简单的服务提供者工具。
系统工具
命令行I/O对象
系统属性
System 类维护一个 Properties 对象,该对象描述当前工作环境的配置。
系统属性包括有关当前用户、Java 运行时的当前版本以及用于分隔文件路径名称的组件的字符的信息。
“file.separator”,“java.class.path”,“java.home”,“java.vendor”,“java.vendor.url” ,“java.version”,“line.separator”,“os.arch”,“os.name”,“os.version”,“path.separator”,“user.dir”,“user.home”,“user.name”
读取系统属性
写入系统属性
安全管理器
为应用程序定义安全策略的对象。
此策略指定不安全或敏感的操作。
安全策略不允许的任何操作都会引发SecurityException。
应用程序还可以查询其安全管理器,以发现允许哪些操作。
通常,web applet 运行时带有浏览器或 Java web Start插件提供的安全管理器。其他类型的应用程序通常在没有安全管理器的情况下运行,除非应用程序本身定义了安全管理器。如果没有安全管理器,则应用程序没有安全策略,操作不受限制。
与安全管理器交互
System.getSecurityManager
一旦应用程序拥有对安全管理器对象的引用,它就可以请求执行特定操作的权限。
SecurityManager 类定义了许多用于验证其他类型操作的其他方法
识别安全违规
其他
arrayCopy
currentTimeMillis,nanoTime
exit
PATH 和 CLASSPATH
java.util.regex API 与正则表达式进行模式匹配
介绍
什么是正则表达式
正则表达式如何在这个包中表示
java.util.regex 包的主要组成
Pattern
Matcher
PatternSyntaxException
测试工具
字符串字面量
此 API 支持的模式匹配的最基本形式是字符串文字的匹配。
元字符
一个由匹配器解释的具有特殊含义的字符。
支持的元字符 : <([{^-=$!|]})?*+.>
强制元字符被视为普通字符
字符类
预定义字符类
量词
允许指定要匹配的出现次数
?* + {n} {n, } {n,m}
零长度匹配
出现情况
用量词捕获组和字符类
三种量词的区别
贪婪
不情愿
所有格
捕获组
是一种将多个字符视为单个单元的方法。
是通过将要分组的字符放置在一组括号中来创建的。
编号
反向引用
边界匹配
Pattern 类的方法
创建带有标志的 Pattern
Pattern 类定义了一个可选的编译方法,该方法接受一组影响模式匹配方式的标志。flags 参数是位掩码,可以包括以下任何一个公共静态字段
Pattern.CANON_EQ
Pattern.CASE_INSENSITIVE
Pattern.COMMENTS
Pattern.DOTALL
Pattern.LITERAL
Pattern.MULTILINE
Pattern.UNICODE_CASE
Pattern.UNIX_LINES
要编译具有多个标志的模式,请使用按位或运算符“|”分隔要包含的标志。
嵌套标志的表达式
使用 matches(String,CharSequence) 方法
使用 split(String) 方法
其他实用方法
java.lang.String 中等价 Pattern 的方法
Matcher 类的方法
索引方法
搜索方法
替换方法
start 和 end 方法
matches 和 lookingAt 方法
replaceFirst(String) 和 replaceAll(String)
appendReplacement(StringBuffer,String) 和appendTail(StringBuffer)
在 java.lang.String 中等价的方法
PatternSyntaxException 类的方法
Unicode 支持
在JDK 7发行版中,正则表达式模式匹配扩展了功能,支持 Unicode 6.0。
匹配特定的代码点
Unicode 字符属性
其他资源
集合——有时称为容器——是一个对象,它将多个元素组合成一个单元。
集合用于存储、检索、操作和通信聚合数据。
集合框架
表示和操作集合的统一体系结构。
组成
接口
实现
算法
Java 集合框架的好处
核心集合接口
Collection
Set
List
Queue
Deque
Map
所有核心集合接口都是泛型的
为了保持核心集合接口的数量易于管理,Java 平台没有为每种集合类型的每种变体提供单独的接口。(这些变体可能包括不可变的、固定大小的和仅追加的。)
相反,每个接口中的修改操作都是可选的——一个给定的实现可以选择不支持所有操作。如果调用了不受支持的操作,集合将抛出 UnsupportedOperationException 异常。
实现负责记录它们支持哪些可选操作。
所有 Java 平台的通用实现都支持所有可选操作。
Collection
集合层次结构的根。
表示一组被称为元素的对象。
Collection 接口是所有集合实现的最小公约数,用于传递集合,并在需要最大通用性时对它们进行操作。
Java 平台不提供该接口的任何直接实现,但提供了更具体的子接口的实现,如 Set 和 List。
按照惯例,所有通用目的的集合实现都有一个接受collection 参数的构造函数。这个构造函数称为转换构造函数,它初始化新集合以包含指定集合中的所有元素,而不管给定集合的子接口或实现类型是什么。换句话说,它允许您转换集合的类型。
基本方法
操作整个集合的方法
数组操作
获取顺序流或并行流
遍历集合
使用聚合操作
使用 for-each 构造
使用迭代器。
Iterator 是一个对象,它使您能够遍历集合,并根据需要有选择地从集合中删除元素。
通过调用集合的 iterator 方法,可以获得集合的Iterator。
如果迭代有更多元素,hasNext 方法返回 true, next 方法返回迭代中的下一个元素。remove 方法从底层Collection中 删除 next 返回的最后一个元素。remove 方法在每次调用 next 时只能被调用一次,如果违反此规则则抛出异常。
Iterator.remove 是在迭代过程中修改集合的唯一安全的方法;如果在迭代正在进行中,如果底层集合以其他方式修改,则该行为将被修改。
使用时机
Set
不能包含重复元素的集合。
该接口为数学集合抽象建模,并用于表示集合
Set 接口只包含从 Collection 继承的方法,并添加了禁止重复元素的限制。
Set 还在 equals 和 hashCode 操作的行为上添加了更强的契约,允许 Set 实例进行有意义的比较,即使它们的实现类型不同。如果两个 Set 实例包含相同的元素,则它们是相等的。
通用实现
HashSet
TreeSet
LinkedHashSet
基本操作
批量操作
数组操作
List
有序集合(有时称为序列)。
列表可以包含重复的元素。
List 的用户通常可以精确地控制每个元素在列表中的插入位置,并且可以通过它们的整数索引(位置)访问元素。
与 Set 接口一样,List 加强了对 equals 和 hashCode 方法的要求,以便可以比较两个 List 对象的逻辑相等性,而不考虑它们的实现类。如果两个 List 对象以相同的顺序包含相同的元素,则它们是相等的。
额外的操作
位置访问
搜索
迭代器
范围视图
Collections.shuffle
Arrays.asList
List 算法
Queue
用于处理前保存多个元素的集合。
除了基本的 Collection 操作之外,Queue 还提供额外的插入、提取和检查操作。
失败时抛出异常
失败时返回特殊值
队列通常(但不一定)以 FIFO (先进先出)方式对元素进行排序。
优先级队列是例外,它根据提供的比较器或元素的自然顺序对元素进行排序。
无论使用何种顺序,队列的头都是将通过调用 remove 或 poll 删除的元素。
在 FIFO 队列中,所有新元素都插入到队列的尾部。其他类型的队列可能使用不同的放置规则。
每个 Queue 实现必须指定其排序属性。
有界队列
队列实现通常不允许插入空元素。LinkedList 实现是一个例外,它被改造为实现 Queue。由于历史原因,它允许空元素,但您应该避免利用这一点,因为 null 被 poll 和peek 方法用作特殊的返回值。
队列实现通常不定义 equals 和 hashCode 方法的基于元素的版本,而是从 Object 继承基于标识的版本。
Queue 接口没有定义阻塞队列方法,而阻塞队列方法在并发编程中很常见。这些方法在接口 java.util.concurrent 中定义,用于等待元素出现或等待空间可用。BlockingQueue,它扩展了 Queue。
Deque
Map
将键映射到值的对象。
Map 不能包含重复的键;每个键最多可以映射到一个值。
加强了对 equals 和 hashCode 方法的要求,以便可以比较两个 Map 对象的逻辑是否相等,而不考虑它们的实现类型。
基本操作
批量操作
集合视图
keySet, entrySet, values
映射代数
通用实现
多重映射
对象排序
Collections.sort
Comparable 接口
编写自己的可比类型
Comparator
SortedSet
按升序保持其元素的集合。
提供了几个额外的操作来利用排序。
范围视图
端点
比较器访问
尽管接口不能保证,但 Java 平台的 SortedSet 实现的toString 方法将返回一个字符串,其中按顺序包含已排序集合的所有元素。
标准构造函数
SortedMap
管道与流
管道是一系列聚合操作
管道的组成
一个源
零或多个中间操作
一个终端操作
流是元素的序列。与集合不同,它不是存储元素的数据结构。相反,流通过管道携带来自源的值。
聚合操作和迭代器的区别
他们使用内部迭代
它们处理来自流的元素
它们支持行为作为参数
约简
约简操作
Stream.reduce 方法
通用的约简操作
参数
identity
accumulator
Stream.collect 方法
与 reduce 方法(在处理元素时总是创建一个新值)不同,collect 方法修改或改变现有值。
参数
supplier
accumulator
combiner
注意
Collectors 类
下游收集器
多级还原
Collectors.reducing 方法
并行
聚合操作和并行流使您能够使用非线程安全的集合实现并行性,前提是在对集合进行操作时不修改集合。
并行执行流
减少并发
并发缩减
执行条件
顺序
副作用
如果一个方法或表达式除了返回或产生一个值之外,还修改了计算机的状态,那么它就会产生副作用。
永远不要在过滤器和映射等操作中将有副作用的 lambda表达式作为参数传递。
惰性
干扰
有状态的 Lambda 表达式
分类
通用实现
Set
List
Queue
Deque
Map
每个通用实现都提供其接口中包含的所有可选操作。所有都允许空元素、键和值。没有同步(线程安全)。
它们都具有快速失败迭代器,可以在迭代过程中检测非法的并发修改,并快速而干净地失败,而不是在未来不确定的时间冒任意的、不确定的行为的风险。
它们都是 Serializable,并且都支持公共克隆方法。
这些实现是不同步的这一事实代表了与过去的决裂(遗留集合 Vector 和 Hashtable 是同步的)
一般来说,不让用户为他们不使用的功能付费是一个很好的 API 设计实践。
此外,在某些情况下,不必要的同步可能导致死锁。
如果您需要线程安全的集合,同步包装器允许将任何集合转换为同步集合。因此,同步对于通用实现是可选的,而对于遗留实现是必须的。
java.util.concurrent 包提供了扩展 Queue 的BlockingQueue 接口和扩展 Map 的 ConcurrentMap 接口的并发实现。这些实现比单纯的同步实现提供了更高的并发性。
通常,您应该考虑接口,而不是实现。在大多数情况下,实现的选择只影响性能。
要记住的一点是,这种性能指标有其局限性。有时,名义上较慢的实现可能更快。当你有疑问的时候,测试你的性能!
特殊实现
并发实现
包装器实现
便利实现
抽象实现
Set 实现
通用实现
特殊实现
List 实现
通用实现
特殊实现
Map 实现
通用实现
特殊实现
并发实现
Queue 实现
通用实现
并发实现
Deque 实现
通用实现
并发实现
包装器 实现
将其所有实际工作委托给指定的集合,但在该集合提供的功能之上添加额外的功能。
这些实现是匿名的;标准库提供的不是公共类,而是静态工厂方法。
所有这些实现都可以在 Collections 类中找到,该类仅由静态方法组成。
同步包装器
不可变包装器
已检查包装器
便利实现
通过静态工厂方法而不是公共类提供
当您不需要它们的全部功能时,它们比通用实现更方便、更高效。
数组的 List 视图
不可变多拷贝 List
Collections.nCopies
用途
不可变单例 Set
Collections.singleton
用途
空 Set, List, 和 Map 常量
Collections 类
所有方法都采用静态方法的形式,其第一个参数是要对其执行操作的集合。
Java 平台提供的绝大多数算法都在 List 实例上操作,但也有少数算法在任意 Collection 实例上操作
排序
洗牌
常规数据操作
搜索
构成
frequency
disjoint
极值
借助 Java 平台提供的抽象实现
动机
持久性
专用
高性能,特殊用途
高性能、多用途的
增强功能
方便
适配
编写
兼容性
向上兼容性
旧 API 返回一个对象数组,而新 API 需要一个 Collection
如果旧的 API 返回 Vector 或 Hashtable,则根本不需要做任何工作,因为 Vector 被改造为实现 List 接口,而Hashtable 被改造为实现 Map。因此,Vector 可以直接传递给调用 Collection 或 List 的任何方法。
API 可能返回表示对象集合的 Enumeration。Collections.list 方法将枚举转换为集合。
向下兼容
新的 API 返回一个 Collection,而旧的 API 需要一个Object 数组。toArray
如果旧的 API 需要 String 数组
如果旧的 API 需要 Vector,标准的集合构造函数就会派上用场。
如果旧 API 需要枚举
API 设计
参数
返回值
遗留的 API
Date-Time 包,java.time。在Java SE 8发行版中引入,提供了一个全面的日期和时间模型。
Date-Time API 使用 ISO-8601中定义的日历系统作为默认日历。此日历基于公历系统,并在全球范围内用作表示日期和时间的事实上标准。
如果你想使用另一种日历系统,java.time.chrono 包允许您使用一种预定义的日历系统。或者你也可以自己创建。
Date-Time API 使用 Unicode 公共区域数据存储库(CLDR)。这个存储库支持世界上的语言,并包含世界上最大的可用语言环境数据集合。这个存储库中的信息已经本地化为数百种语言。
Date-Time API 还使用时区数据库(TZDB)。该数据库提供了自1970年以来全球每次时区变化的信息,以及自该概念引入以来主要时区的历史。
清晰
流畅
不可变
可扩展
java.time
java.time.chrono
java.time.format
java.time.temporal
java.time.zone
类之间的方法名尽可能保持一致。
方法名前缀
of
from
parse
format
get
is
with
plus
minus
to
at
简介
时间表示方法
在选择基于时间的类时,首先决定需要表示人类时间还是机器时间。然后确定需要表示时间的哪些方面。
java中基于时间的类
Instant
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
Year
Month
YearMonth
MonthDay
OffsetTime
OffsetDateTime
Duration
Period
秒被捕捉到纳秒的精度。
部分类不存储此信息,但具有以这些单位提供时间的方法
将 Period 添加到 ZonedDateTime 时,将观察夏时制或其他当地时间差异。
DayOfWeek 和 Month 枚举
日期类
专门处理日期信息,而不考虑时间或时区。
LocalDate
YearMonth
MonthDay
Year
日期和时间类
LocalTime
LocalDateTime
时区和偏移类
时区是地球上使用相同标准时间的区域。
每个时区都由一个标识符描述,通常有格式 区域/城市 和来自格林威治时间的偏移量。
ZoneId
ZoneOffset
日期-时间类
使用时区的基于时间的类
ZonedDateTime
OffsetDateTime
OffsetTime
尽管这三个类都维护了一个格林威治时间的偏移量,但只有 ZonedDateTime 使用 java.time.zone 包的ZoneRules 来确定特定时区的偏移量如何变化。
Instant 类
解析与格式化
DateTimeFormatter 类
解析
LocalDate.parse()
格式化器
预定义
自定义
格式化
temporal 包
提供了一组接口、类和枚举,用于支持日期和时间代码,特别是日期和时间计算。
这些接口用于最底层。典型的应用程序代码应该根据具体类型(如 LocalDate 或 ZonedDateTime)来声明变量和参数,而不是根据 Temporal 接口。
Temporal 和 TemporalAccessor
ChronoField 和 IsoFields
ChronoUnit
时间调整器
TemporalAdjuster 接口
预定义调节器
自定义调节器
时间查询
TemporalQuery
预定义查询
自定义查询
Period 和 Duration
指定时间量
Duration 使用基于时间的值(秒、纳秒)度量时间量。Period 使用基于日期的值(年、月、日)。
Duration
ChronoUnit
Period
Clock 类
非iso日期转换
转换为非iso的日期
转换为基于iso的日期
遗留日期-时间代码
在 Java SE 8发布之前,Java 日期和时间机制是由java.util.Date, java.util.Calendar, and java.util.TimeZone 提供
缺点
与遗留代码的互操作性
java.util Date and Time 到 java.time 功能映射
日期和时间格式
Java 富网络应用程序(RIA)是一种具有与桌面应用程序相似特征的应用程序,但是通过网络进行部署。Java ria 可以作为 Java applet 或 Java Web Start 应用程序开发和部署。
applet——Java applet 在浏览器上下文中运行。Java 插件软件控制 Java applet 的执行和生命周期。
Java Web Start 应用程序——Java Web Start 应用程序第一次通过浏览器启动。它们随后可能会从桌面快捷方式启动。一旦下载了 Java Web Start 应用程序,并且用户接受了它的安全证书,它的行为几乎就像一个独立的应用程序。
一个自包含的应用程序由一个单独的可安装的包组成,该包包含您的应用程序和运行应用程序所需的 JRE 副本。当安装应用程序时,它的行为与任何本地应用程序相同。为用户提供一个自包含的应用程序可以避免与在浏览器中运行应用程序有关的安全问题。
您可以通过提供自己的图标来定制自包含的应用程序。可以设置文件关联,这样当用户打开应用程序可以处理的文件时,应用程序就会自动启动。支持多个入口点,因此您可以在单个自包含的应用程序包中交付一套应用程序。
可以使用 Java 打包工具打包自包含的应用程序。javapackager 命令从命令行为自包含的应用程序创建包。NetBeans 还可以用于创建自包含的应用程序包。
打包自包含应用程序的先决条件
编译和打包应用程序需要 Java 开发工具包 (JDK)。必须在运行自包含应用程序的平台上创建可安装包
第三方工具
Windows
EXE
MSI
Linux
RPM
DEB
OS X
转换现有应用程序
任何独立的 Java 应用程序或 Java Web Start 应用程序都可以打包为自包含的应用程序。
从部署 Java Web Start 应用程序转换为自包含应用程序
使用文件关联
为用户提供自包含应用程序的优点之一是能够建立文件关联。可以根据 MIME 类型或文件扩展名将特定类型的文件与应用程序相关联,以便使用应用程序打开相关文件。
建立文件关联
从关联文件启动
启动应用程序所采取的操作取决于运行应用程序的平台。
Linux 和 Windows
OS X
更多关于文件关联演示
添加外部库
提供默认参数
为所有平台使用公共构建文件
使用多个入口点
Java™Archive (JAR)文件格式使您能够将多个文件捆绑到单个归档文件中。
通常,JAR 文件包含与 applet 和应用程序相关联的类文件和辅助资源。
JAR文件格式的好处
安全
减少下载时间
压缩
扩展的打包
包密封
包版本
可移植性
使用JAR文件
JAR 文件是用 ZIP 文件格式打包的,因此您可以将它们用于无损数据压缩、归档、解压缩和归档解包等任务。这些任务是 JAR 文件最常见的用途之一,仅使用这些基本特性就可以实现许多 JAR 文件的好处。
要使用 JAR 文件执行基本任务,您可以使用作为 Java 开发工具包(JDK)一部分提供的 Java 存档工具。因为 Java Archive工具是通过使用 jar 命令调用的,所以本教程将其称为“jar工具”。
创建JAR文件
jar cf jar-file input-file(s)
c 选项表示您想要创建一个 JAR 文件。
f 选项表示希望输出到文件中,而不是到标准输出中。
jar-file 是您希望生成的 JAR 文件具有的名称。您可以为JAR 文件使用任何文件名。按照惯例,JAR 文件名的扩展名是. JAR,尽管这不是必需的。
input-file(s) 参数是一个以空格分隔的列表,其中包含您希望包含在 JAR 文件中的一个或多个文件。input-file 参数可以包含通配符*符号。如果任何“输入文件”是目录,那么这些目录的内容将被递归地添加到 JAR 存档中。
c 和 f 选项可以任意一种顺序出现,但它们之间不能有任何空格。
该命令将生成一个压缩 JAR 文件,并将其放置在当前目录中。该命令还将为 JAR 存档生成一个默认清单文件。
JAR 文件中的元数据,例如条目名称、注释和清单的内容,必须用 UTF8 编码。
Jar命令选项
v
0(零)
M
m
-C
查看JAR文件的内容
提取JAR文件的内容
运行打包为JAR文件的应用程序
包装在 JAR 文件中的 applet
JAR文件作为应用程序
更新JAR文件
使用 manifest 文件
JAR 文件支持广泛的功能,包括电子签名、版本控制、包密封等。是什么赋予 JAR 文件如此多功能性?答案是 JAR文件的清单。
清单是一个特殊的文件,可以包含关于 JAR 文件中打包的文件的信息。通过裁剪清单所包含的“元”信息,您可以使 JAR 文件服务于各种目的。
理解默认清单
当您创建一个 JAR 文件时,它会自动接收一个默认的清单文件。存档中只能有一个清单文件,并且它总是有路径名 META-INF/MANIFEST.MF
包含内容
清单的条目采用“头:值”对的形式。标头的名称与其值之间用冒号分隔。
清单还可以包含关于打包在存档中的其他文件的信息。清单中应该记录哪些文件信息取决于您打算如何使用 JAR 文件。默认清单没有假设它应该记录关于其他文件的什么信息。
摘要信息不包括在默认清单中。
修改清单文件
设置应用程序的入口点
Main-Class: classname
使用 JAR 工具设置入口点
向JAR文件的类路径中添加类
设置包版本信息
Name
Specification-Title
Specification-Version
Specification-Vendor
Implementation-Title
Implementation-Version
Implementation-Vendor
在JAR文件中密封包
使用清单属性增强安全性
Permissions
Codebase
Application-Name
Application-Library-Allowable-Codebase
Caller-Allowable-Codebase
Entry-Point
Trusted-Only
Trusted-Library
签名和验证JAR文件
您可以选择使用您的电子“签名”对 JAR 文件进行签名。验证签名的用户可以授予与 jar 绑定的软件通常不具备的安全特权。相反,您可以验证希望使用的已签名JAR文件的签名。
理解签名与验证
您对文件进行数字签名的原因与您用钢笔和墨水在纸质文档上签名的原因相同——让读者知道文档是您写的,或者至少该文档得到了您的批准。
当对 JAR 文件进行签名时,您还可以选择对签名加盖时间戳。与在纸质文档上添加日期类似,签名的时间戳可以识别 JAR 文件的签名时间。时间戳可用于验证用于签名JAR 文件的证书在签名时是否有效。
签名和验证文件的能力是 Java 平台安全体系结构的重要组成部分。安全性由运行时生效的安全策略控制。您可以配置策略,为小程序和应用程序授予安全特权。
Java 平台通过使用称为公钥和私钥的特殊数字来支持签名和验证。公钥和私钥是成对出现的,它们的作用是互补的。
仅靠公钥和私钥还不足以真正验证签名。即使您已经验证了签名文件包含一个匹配的密钥对,您仍然需要某种方法来确认公钥实际上来自它声称来自的签名者。
签名和验证工作还需要一个因素。附加的元素是签名者包含在已签名 JAR 文件中的证书。证书是来自公认的证书颁发机构的数字签名声明,它指示谁拥有特定的公钥。
当您对 JAR 文件进行签名时,您的公钥将与关联的证书一起放置在存档中,以便任何想要验证您的签名的人都可以轻松使用它。
摘要和签名文件
签名块文件
除了签名文件之外,当对 JAR 文件进行签名时,还会自动将签名块文件放在 META-INF 目录中。
与清单文件或签名文件不同,签名块文件不是人类可读的。
主要元素
签名块文件名通常具有. dsa 扩展名,表明它们是由默认的数字签名算法创建的。如果使用与其他标准算法相关联的密钥进行签名,则可以使用其他文件扩展名。
签名JAR文件
要对 JAR 文件进行签名,首先必须有一个私钥。私钥及其相关的公钥证书存储在名为密钥存储库的受密码保护的数据库中。密钥存储库可以保存许多潜在签名者的密钥。密钥存储库中的每个密钥都可以通过一个别名来标识,该别名通常是拥有该密钥的签名者的名称。
jarsigner jar-file alias
Jarsigner工具将提示您输入密钥库和别名的密码。
该命令的基本形式假设要使用的密钥存储库位于主目录中名为 .keystore 的文件中。它将分别创建名称为 x.SF 和 x.DSA 的签名和签名块文件,其中x是别名的前八个字母,全部转换为大写字母。这个基本命令将用签名的 JAR文件覆盖原始 JAR 文件。
Jarsigner命令选项
-keystore url
-sigfile file
-signedjar file
-tsa url
-tsacert alias
-altsigner class
-altsignerpath classpathlist
验证已签名的JAR文件
使用与jar相关的api
java.util.jar
java.net.JarURLConnection
java.net.URLClassLoader
JarClassLoader 类
扩展了 java.net.URLClassLoader
构造函数
getMainClassName 方法
JarURLConnection 类和 JAR URLs
java.net.JarURLConnection 类
获取清单属性
invokeClass 方法
参考链接:The Java Tutorials
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。