具体的原理最好是ȝ《深入java虚拟机》,里面对jsr、ret{几个指令做了详l的说明。这里不深入分析Q而仅仅是从表现Ş式上看一下finally的特征?/span>
代码Q?/span>
/*
* author: Zang XT
*/
public class TestFinal {
public static void main(String[] args) {
System.out.println("test1:" + testFinal1());
System.out.println("test2:" + testFinal2());
System.out.println("test3:" + testFinal3());
System.out.println("test4:" + testFinal4());
}
static int testFinal1() {
int i = 1;
try {
return i;
} finally {
System.out.println("in testFinal1():finally 肯定会被执行的!");
i = 48;
}
}
static String testFinal2() {
String str = "try";
try {
return str;
} finally {
System.out.println("in testFinal2():finally 肯定会被执行的!");
str = "finally";
}
}
static StringBuilder testFinal3() {
StringBuilder build = new StringBuilder("try ");
try {
return build;
} finally {
System.out.println("in testFinal3():finally 肯定会被执行的!");
build.append("finally");
build = new StringBuilder("你猜我是谁!");
}
}
static String testFinal4() {
try {
return "return in try";
} finally {
System.out.println("in testFinal4():finally 肯定会被执行的!");
return "return in finally";
}
}
}
输出是:
in testFinal1():finally 肯定会被执行的!
test1:1
in testFinal2():finally 肯定会被执行的!
test2:try
in testFinal3():finally 肯定会被执行的!
test3:try finally
in testFinal4():finally 肯定会被执行的!
test4:return in finally
HashMap:
Z哈希表的 Map 接口的实现。此实现提供所有可选的映射操作Q?span style="color: red;">q允怋?null 值和 null 键。(除了不同步和允许使用 null 之外QHashMap cM Hashtable 大致相同。)此类不保证映的序Q特别是它不保证该顺序恒久不变?nbsp;
此实现假定哈希函数将元素正确分布在各桶之_可ؓ基本操作Qget ?putQ提供稳定的性能?span style="color: red;">q代集合视图所需的时间与 HashMap 实例?#8220;定w”Q桶的数量)及其大小Q键-值映关pLQ的和成比例。所以,如果q代性能很重要,则不要将初始定w讄得太高(或将加蝲因子讄得太低)?
HashMap 的实例有两个参数影响其性能Q初始容量和加蝲因子。容量是哈希表中桶的数量Q初始容量只是哈希表在创建时的容量。加载因?
是哈希表在其定w自动增加之前可以辑ֈ多满的一U尺度。当哈希表中的条目数出了加载因子与当前定w的乘U时Q通过调用 rehash
Ҏ容量翻倍?
通常Q?span style="color: rgb(32, 88, 255);">默认加蝲因子 (.75) 在时间和I间成本上寻求一U折?/span>?
加蝲因子q高虽然减少了空间开销Q但同时也增加了查询成本Q在大多?HashMap cȝ操作中,包括 get ?put
操作Q都反映了这一点)。在讄初始定w时应该考虑到映中所需的条目数及其加蝲因子Q以便最大限度地降低 rehash
操作ơ数。如果初始容量大于最大条目数除以加蝲因子Q则不会发生 rehash 操作?
如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动?rehash 操作以增大表的容量来_使用_大的初始定w创徏它将使得映射关系能更有效地存储?
注意Q?span style="color: rgb(255, 0, 0);">此实C是同步的。如果多个线E同时访问此映射Q而其中至一个线E从l构上修改了该映,则它必须保持外部同步。(l构上的修改是指d或删除一个或多个映射关系的操作;仅改变与实例已经包含的键兌的g是结构上的修?/span>。)q一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在q样的对象,则应该?Collections.synchronizedMap Ҏ?#8220;包装”该映。最好在创徏时完成这一操作Q以防止Ҏ进行意外的不同步访问,如下所C:
Map m = Collections.synchronizedMap(new HashMap(...));
由所有此cȝ“集合视图Ҏ”所q回的P代器都是快速失败的Q?
在P代器创徏之后Q如果从l构上对映射q行修改Q除非通过q代器自w的 remove ?add ҎQ其他Q何时间Q何方式的修改QP代器都将抛出
ConcurrentModificationException。因此,面对q发的修改,q代器很快就会完全失败,而不冒在来不确定的旉L发生?
定行ؓ的风险?
注意QP代器的快速失败行Z能得C证,一般来_存在不同步的q发修改Ӟ不可能作ZQ何坚决的保证。快速失败P代器最大努力抛?
ConcurrentModificationException。因此,~写依赖于此异常E序的方式是错误的,正确做法是:q代器的快速失败行为应该仅
用于程序错误?nbsp;
Hashtable:
此类实现一个哈希表Q该哈希表将键映到相应的倹{?span style="color: rgb(255, 0, 0);">M?null 对象都可以用作键或?/span>?br />
Z成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode Ҏ?equals Ҏ?br />
Hashtable
的实例有两个参数影响其性能Q初始容量和加蝲因子。容量是哈希表中桶的数量Q初始容量就是哈希表创徏时的定w。注意,哈希表的状态ؓ
openQ在发生“哈希冲突”的情况下Q单个桶会存储多个条目,q些条目必须按顺序搜索。加载因子是对哈希表在其定w自动增加之前可以辑ֈ多满的一个尺
度。初始容量和加蝲因子q两个参数只是对该实现的提示。关于何时以及是否调?rehash Ҏ的具体细节则依赖于该实现?br />
通常Q默认加载因?.75)在时间和I间成本上寻求一U折街加载因子过高虽然减了I间开销Q但同时也增加了查找某个条目的时_在大多数 Hashtable 操作中,包括 get ?put 操作Q都反映了这一点)?br />
初始定w主要控制I间消耗与执行 rehash 操作所需要的旉损耗之间的q。如果初始容量大于Hashtable 所包含的最大条目数除以加蝲因子Q则永远不会发生 rehash 操作。但是,初始容量设|太高可能会费I间?br />
如果很多条目要存储在一?Hashtable 中,那么与根据需要执行自?rehashing 操作来增大表的容量的做法相比Q用够大的初始容量创建哈希表或许可以更有效地插入条目?br />
下面q个CZ创徏了一个数字的哈希表。它数字的名称用作键:
要检索一个数字,可以使用以下代码Q?
?Java 2 q_ v1.2 以来Q此cdl改qؓ可以实现 MapQ因此它变成?Java Collections Framework 的一部分。与新集合的实现不同QHashtable 是同步的?br />
pP代器q回?Iterator 和由所?Hashtable ?#8220;collection 视图Ҏ”q回?Collection ?
listIterator Ҏ都是快速失?的:在创?Iterator 之后Q如果从l构上对 Hashtable q行修改Q除非通过
Iterator 自n的移除或dҎQ否则在M旉以Q何方式对其进行修改,Iterator 都将抛出
ConcurrentModificationException。因此,面对q发的修改,Iterator
很快׃完全p|Q而不冒在来某个不确定的旉发生L不确定行为的风险。由 Hashtable 的键和值方法返回的 Enumeration ?
是快速失败的?
注意QP代器的快速失败行为无法得C证,因ؓ一般来_不可能对是否出现不同步ƈ发修改做ZQ何硬性保证。快速失败P代器会尽最大努力抛?
ConcurrentModificationException。因此,为提高这cP代器的正性而编写一个依赖于此异常的E序是错误做法:q代器的?
速失败行为应该仅用于程序错误?
HashMap:
Z哈希表的 Map 接口的实现。此实现提供所有可选的映射操作Q?span style="color: red;">q允怋?null 值和 null 键。(除了不同步和允许使用 null 之外QHashMap cM Hashtable 大致相同。)此类不保证映的序Q特别是它不保证该顺序恒久不变?nbsp;
此实现假定哈希函数将元素正确分布在各桶之_可ؓ基本操作Qget ?putQ提供稳定的性能?span style="color: red;">q代集合视图所需的时间与 HashMap 实例?#8220;定w”Q桶的数量)及其大小Q键-值映关pLQ的和成比例。所以,如果q代性能很重要,则不要将初始定w讄得太高(或将加蝲因子讄得太低)?
HashMap 的实例有两个参数影响其性能Q初始容量和加蝲因子。容量是哈希表中桶的数量Q初始容量只是哈希表在创建时的容量。加载因?是哈希表在其定w自动增加之前可以辑ֈ多满的一U尺度。当哈希表中的条目数出了加载因子与当前定w的乘U时Q通过调用 rehash Ҏ容量翻倍?
通常Q?span style="color: #2058ff;">默认加蝲因子 (.75) 在时间和I间成本上寻求一U折?/span>。加载因子过高虽然减了I间开销Q但同时也增加了查询成本Q在大多?HashMap cȝ操作中,包括 get ?put 操作Q都反映了这一点)。在讄初始定w时应该考虑到映中所需的条目数及其加蝲因子Q以便最大限度地降低 rehash 操作ơ数。如果初始容量大于最大条目数除以加蝲因子Q则不会发生 rehash 操作?
如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动?rehash 操作以增大表的容量来_使用_大的初始定w创徏它将使得映射关系能更有效地存储?
注意Q?span style="color: #ff0000;">此实C是同步的。如果多个线E同时访问此映射Q而其中至一个线E从l构上修改了该映,则它必须保持外部同步。(l构上的修改是指d或删除一个或多个映射关系的操作;仅改变与实例已经包含的键兌的g是结构上的修?/span>。)q一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在q样的对象,则应该?Collections.synchronizedMap Ҏ?#8220;包装”该映。最好在创徏时完成这一操作Q以防止Ҏ进行意外的不同步访问,如下所C:
Map m = Collections.synchronizedMap(new HashMap(...));
由所有此cȝ“集合视图Ҏ”所q回的P代器都是快速失败的Q在q代器创Z后,如果从结构上Ҏ进行修改,除非通过q代器自w的 remove ?add ҎQ其他Q何时间Q何方式的修改QP代器都将抛出 ConcurrentModificationException。因此,面对q发的修改,q代器很快就会完全失败,而不冒在来不确定的旉L发生不确定行为的风险?
注意QP代器的快速失败行Z能得C证,一般来_存在不同步的q发修改Ӟ不可能作ZQ何坚决的保证。快速失败P代器最大努力抛?ConcurrentModificationException。因此,~写依赖于此异常E序的方式是错误的,正确做法是:q代器的快速失败行为应该仅用于程序错误?nbsp;
Hashtable:
此类实现一个哈希表Q该哈希表将键映到相应的倹{?span style="color: #ff0000;">M?null 对象都可以用作键或?/span>?br />
Z成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode Ҏ?equals Ҏ?br />
Hashtable 的实例有两个参数影响其性能Q初始容量和加蝲因子。容量是哈希表中桶的数量Q初始容量就是哈希表创徏时的定w。注意,哈希表的状态ؓ openQ在发生“哈希冲突”的情况下Q单个桶会存储多个条目,q些条目必须按顺序搜索。加载因子是对哈希表在其定w自动增加之前可以辑ֈ多满的一个尺度。初始容量和加蝲因子q两个参数只是对该实现的提示。关于何时以及是否调?rehash Ҏ的具体细节则依赖于该实现?br />
通常Q默认加载因?.75)在时间和I间成本上寻求一U折街加载因子过高虽然减了I间开销Q但同时也增加了查找某个条目的时_在大多数 Hashtable 操作中,包括 get ?put 操作Q都反映了这一点)?br />
初始定w主要控制I间消耗与执行 rehash 操作所需要的旉损耗之间的q。如果初始容量大于Hashtable 所包含的最大条目数除以加蝲因子Q则永远不会发生 rehash 操作。但是,初始容量设|太高可能会费I间?br />
如果很多条目要存储在一?Hashtable 中,那么与根据需要执行自?rehashing 操作来增大表的容量的做法相比Q用够大的初始容量创建哈希表或许可以更有效地插入条目?br />
下面q个CZ创徏了一个数字的哈希表。它数字的名称用作键:
要检索一个数字,可以使用以下代码Q?
?Java 2 q_ v1.2 以来Q此cdl改qؓ可以实现 MapQ因此它变成?Java Collections Framework 的一部分。与新集合的实现不同QHashtable 是同步的?br />
pP代器q回?Iterator 和由所?Hashtable ?#8220;collection 视图Ҏ”q回?Collection ?listIterator Ҏ都是快速失?的:在创?Iterator 之后Q如果从l构上对 Hashtable q行修改Q除非通过 Iterator 自n的移除或dҎQ否则在M旉以Q何方式对其进行修改,Iterator 都将抛出 ConcurrentModificationException。因此,面对q发的修改,Iterator 很快׃完全p|Q而不冒在来某个不确定的旉发生L不确定行为的风险。由 Hashtable 的键和值方法返回的 Enumeration ?是快速失败的?
注意QP代器的快速失败行为无法得C证,因ؓ一般来_不可能对是否出现不同步ƈ发修改做ZQ何硬性保证。快速失败P代器会尽最大努力抛?ConcurrentModificationException。因此,为提高这cP代器的正性而编写一个依赖于此异常的E序是错误做法:q代器的快速失败行为应该仅用于程序错误?