JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java Certification » SCJP  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 Assertion 介紹與使用 [精華]
swanky

暴走熊

版主

發文: 461
積分: 9
於 2003-08-18 21:53 user profilesend a private message to usersend email to swankyreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
去年的文章

Assertion 是新版 SCJP 考題增加的項目,這東西其實跟 Exception 有點相似
然而它是屬於 java.lang.Error 的東西
我只是介紹他在程式碼中的使用方法
而編譯的使用方法可以先參照下面網址的簡介
http://www.oreilly.com.tw/sleepless/***happen2.htm

原始來源是來自於下面 sun 的文件 Programming With Assertions
http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html

一、 assert的兩種語法:

1
assert Expression1;


Expression1 必須是個 boolean Expression
當 Expression1 為 false 時,會丟出個 AssertionError

1
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:
這是錯的:
1
2
    // Broken! - action is contained in assertion
    assert names.remove(null);


要改成:
1
2
3
    // 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:
原式:
1
2
3
4
5
6
7
    if (i % 3 == 0) {
        ...
    } else if (i % 3 == 1) {
        ...
    } else { // We know (i % 3 == 2)
        ...
    }


後式:
1
2
3
4
5
6
7
8
    if (i % 3 == 0) {
        ...
    } else if (i % 3 == 1) {
        ...
    } else {
        assert i % 3 == 2 : i;
        ...
    }


意思是你原本註解為你已知的事實,可以用 assert 來確保不會錯

ex2:
原式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    switch(suit) {
      case Suit.CLUBS:
        ...
        break;
 
      case Suit.DIAMONDS:
        ...
        break;
 
      case Suit.HEARTS:
        ...
        break;
 
      case Suit.SPADES:
        ...
    }


你通常會在 switch 裡加個 default,這裡就可以用到 assertion

1
2
      default:
        assert false : suit;


或是另一種像是丟出 Exception 的語法

1
2
      default:
        throw new AssertionError(suit); 


這會強制丟出個 AssertionError

˙Control-Flow Invariants

☆place an assertion at any location you assume will not be reached.

語法: assert false;

ex:
原式:
1
2
3
4
5
6
7
    void foo() {
        for (...) {
            if (...)
                return;
        }
        // Execution should never reach this point!!!
    }


後式:
1
2
3
4
5
6
7
    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:
原式:
1
2
3
4
5
6
7
     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);
     }


後式:
1
2
3
4
5
6
    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:
原式:
1
2
3
4
5
6
7
8
9
10
   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) {
       ...
   }


後式:
1
2
3
4
5
    // 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:
1
2
3
4
5
6
7
8
9
    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:
1
2
3
4
5
6
7
8
    原式:
    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.
    }


後式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    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:
1
2
3
4
    // Returns true if this tree is properly balanced
    private boolean balanced() {
        ...
    }


在這 ex 中,加入
1
    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吧


reply to postreply to post
話題樹型展開
人氣 標題 作者 字數 發文時間
23835 [精華] Assertion 介紹與使用 swanky 6668 2003-08-18 21:53
34440 assert 的教學文章 swanky 9895 2003-08-18 21:59
21130 Re:assert 的教學文章 JiaYun 513 2003-09-02 23:51
17130 Re:assert 的教學文章 noland33 22 2004-10-23 23:04
17024 Re:assert 的教學文章 noland33 108 2004-10-24 00:09
17165 Re:assert 的教學文章 Yoshi 867 2004-10-24 00:28
17103 Re:assert 的教學文章 Duncan 1212 2004-10-24 14:45
17485 Re:assert 的教學文章 noland33 87 2004-10-24 16:12
20160 Re:Assertion 介紹與使用 yi 160 2004-04-13 23:48
» JWorld@TW »  Java Certification » SCJP

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8