看板java
标 题[教学] Assertion 介绍与使用
发信站Taipei Municipal Teachers College (Thu Jul 25 17:12:26 2002)
转信站Ptt!news.ntu!freebsd.ntu!ctu-peer!spring!news.nctu!news!news.tmtc!tmtc
Assertion 是新版 SCJP 考题增加的项目,这东西其实跟 Exception 有点相似
然而它是属於 java.lang.Error 的东西
我只是介绍他在程式码中的使用方法
而编译的使用方法可以先参照下面网址的简介
http://www.oreilly.com.tw/sleepless/shithappen2.htm
原始来源是来自於下面 sun 的文件 Programming With Assertions
http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html
一、 assert的两种语法:
assert Expression1;
Expression1 必须是个 boolean Expression
当 Expression1 为 false 时,会丢出个 AssertionError
assert Expression1 : Expression2;
Expression1 是 boolean Expression
Expression2 则是一个值
当 Expression1 为 false 时,会把 Expression2 的值传给 AssertionError 的建构子
二、 把 Assertion 放入程式码
这里分成三个 section
˙Internal Invariants
˙Control-Flow Invariants
˙Preconditions, Postconditions, and Class Invariants
但是先有两个 Assertion 不能使用的重点:
1.Do not use assertions for argument checking in public methods.
意思是请不要把 Assertion 跟 Exception 弄混了,两者做的事是不同的
2.Do not use assertions to do any work that your application requires for
correct operation.
ex:
这是错的:
// Broken! - action is contained in assertion
assert names.remove(null);
要改成:
// Fixed - action precedes assertion
boolean nullsRemoved = names.remove(null);
assert nullsRemoved; // Runs whether or not asserts are enabled
原因似乎是 assertion 预设是 disable,要写的明确点他才能用...
˙Internal Invariants
☆use an assertion whenever you would have written a comment that asserts an
invariant.
ex1:
原式:
if (i % 3 == 0) {
...
} else if (i % 3 == 1) {
...
} else { // We know (i % 3 == 2)
...
}
後式:
if (i % 3 == 0) {
...
} else if (i % 3 == 1) {
...
} else {
assert i % 3 == 2 : i;
...
}
意思是你原本注解为你已知的事实,可以用 assert 来确保不会错
ex2:
原式:
switch(suit) {
case Suit.CLUBS:
...
break;
case Suit.DIAMONDS:
...
break;
case Suit.HEARTS:
...
break;
case Suit.SPADES:
...
}
你通常会在 switch 里加个 default,这里就可以用到 assertion
default:
assert false : suit;
或是另一种像是丢出 Exception 的语法
default:
throw new AssertionError(suit);
这会强制丢出个 AssertionError
˙Control-Flow Invariants
☆place an assertion at any location you assume will not be reached.
语法:
assert false;
ex:
原式:
void foo() {
for (...) {
if (...)
return;
}
// Execution should never reach this point!!!
}
後式:
void foo() {
for (...) {
if (...)
return;
}
assert false; // Execution should never reach this point!
}
就是在你程式执行不到的地方加 assertion
˙Preconditions, Postconditions, and Class Invariants
这里分成:
˙Preconditions
└˙Lock-Status Preconditions
˙Postconditions
˙Class invariants
Preconditions — what must be true when a method is invoked.
☆Do not use assertions to check the parameters of a public method.
ex:
原式:
public void setRefreshRate(int rate) {
// Enforce specified precondition in public method
if (rate <= 0 || rate > MAX_REFRESH_RATE)
throw new IllegalArgumentException("Illegal rate: " + rate);
setRefreshInterval(1000/rate);
}
後式:
private void setRefreshInterval(int interval) {
// Confirm adherence to precondition in nonpublic method
assert interval > 0 && interval <= 1000/MAX_REFRESH_RATE : interval;
... // Set the refresh interval
}
意思是这状况下 assertion 只能出现在 nonpublic 里
请记得这是个 Error,而不是 Exception
Lock-Status Preconditions — preconditions concerning whether or not a given
lock is held.
ex:
原式:
private Object[] a;
public synchronized int find(Object key) {
return find(key, a, 0, a.length);
}
// Recursive helper method - always called with a lock on this object
private int find(Object key, Object[] arr, int start, int len) {
...
}
後式:
// Recursive helper method - always called with a lock on this.
private int find(Object key, Object[] arr, int start, int len) {
assert Thread.holdsLock(this); // lock-status assertion
...
}
意思是可以用 assertion 来检查有没有 lock
Postconditions — what must be true after a method completes successfully.
这种状况可以分别用在 public 与 nonpublic 里
public:
ex:
public BigInteger modInverse(BigInteger m) {
if (m.signum <= 0)
throw new ArithmeticException("Modulus not positive: " + m);
... // Do the computation
assert this.multiply(result).mod(m).equals(ONE) : this;
return result;
}
nonpublic:
ex:
原式:
void foo(int[] array) {
// Manipulate array
...
// At this point, array will contain exactly the ints that it did
// prior to manipulation, in the same order.
}
後式:
void foo(final int[] array) {
// Inner class that saves state and performs final consistency check
class DataCopy {
private int[] arrayCopy;
DataCopy() { arrayCopy = (int[]) array.clone(); }
boolean isConsistent() { return Arrays.equals(array, arrayCopy); }
}
DataCopy copy = null;
// Always succeeds; has side effect of saving a copy of array
assert ((copy = new DataCopy()) != null);
... // Manipulate array
// Ensure array has same ints in same order as before manipulation.
assert copy.isConsistent();
}
使用 inner class 跟这两个 assertion 可以用来确认你的资料
Class invariants — what must be true about each instance of a class.
ex:
// Returns true if this tree is properly balanced
private boolean balanced() {
...
}
在这 ex 中,加入
assert balanced();
是为了确认这个 class 里的 instance
後记:
为了参加 SCJP,这个 Assertion 让我去找了些资料
但是市面上有许多标示 1.4 版的书,根本就没有提到
所以资料几乎都是英文的
像是 O'REILLY 原文新出的 Learning Java, 2nd Edition
http://www.oreilly.com/catalog/learnjava2/
里面就有介绍了,可惜天珑好像还没进货 @.@"
下面是几个我觉得不错的 assertion 介绍
http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html
http://www.javaworld.com/javaworld/jw-11-2001/jw-1109-assert.html
http://www.jcp.org/content/main/jsr/detail/materials/asrt_prop.html
第一个就是我这篇的来源
我只作了非常精简的介绍,想要了解更详细的话,就去看看原本的文章跟API吧
其实我之前对这 assertion 根本没听过...
想说没有 Exception 跟 Assertion 还是一样可以活的很快乐...
也不知道怎麽去测他就是...
希望能有前辈给我们更清楚的说明
也希望想参加新版 SCJP 考试的人能够来一起研究罗~ ^o^"
--
欢迎加入
◢██◣◢██◣█◣ ◣◢██◣☆swanky
██ ██◤███ ███◤█
██ ████◥█◢◤████
◥█◤ ◥█◥◤ ◥◤ ◥█◥◤版的讨论
--
※Post by swanky from u138-246.u61-70.giga.net
▁▃▅▆▄▃▁ ▃▅▂ ▁ ▁▃▄▁
▃▅
欢迎大家到市立师院▄
凯达格兰▆▅▄▇ _▁▃▄▅█▅▄▂▁_▄▃
▇▅▄ ▄▅ ccbbs.tmtc.edu.tw ▂▃▆▇▆▁▂▄▆▆▇████▆▃