[教學] Assertion 介紹與使用

看板java作者時間22年前 (2002/07/25 17:47), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
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 ▂▃▆▇▆▁▂▄▆▆▇████▆▃
文章代碼(AID): #zFyac00 (java)
文章代碼(AID): #zFyac00 (java)