2014年5月16日 星期五

Java 泛型 interface

這篇要介紹的是 interface 使用泛型

至於泛型的定義,這裡有詳細的介紹
http://openhome.cc/Gossip/Java/
http://my.oschina.net/roockee/blog/165378

好~進入主題
前陣子工作上,在寫郵件代收程式
遇上了 POP3, IMAP 的 UID (String, long) 型別不同問題
(有興趣的人可以自己去研究一下這兩個 Protocol)

又因為兩個收信方式的處理有些微的不同,所以使用 Interface 的方式處理


首先,我定義一個 MailReceiver 的 Interface

public interface MailReceiver<T>{

public void init(Folder inbox);

public void doSomething(T uid);

public T getUID(Message msg) throws MessagingException;
}


接著就分別 Implement POP3, IMAP

public class POP3 implements MailReceiver<String> {

private POP3Folder pop3Inbox;

@Override
public String getUID(Message msg) throws MessagingException {
return pop3Inbox.getUID(msg);
}

@Override
public void init(Folder inbox) {
pop3Inbox = (POP3Folder) inbox;
}

@Override
public void doSomething(String uid) {
// TODO Auto-generated method stub

}

}


public class IMAP implements MailReceiver<Long> {

private IMAPFolder imapInbox;

@Override
public Long getUID(Message msg) throws MessagingException {
return imapInbox.getUID(msg);
}

@Override
public void init(Folder inbox) {
imapInbox = (IMAPFolder) inbox;
}

@Override
public void doSomething(Long uid) {
// TODO Auto-generated method stub

}

}


OK, 依照上面的範例
可以看到我不用在像 inbox 變數一樣,要做型別 cast
也避免了會有 ClassCastException 的問題

所以,同樣寫法,我也可以將 inbox 以泛型的寫法改寫,如下

public interface MailReceiver<F,T> {

public void init(F inbox);

public void doSomething(T uid);

public T getUID(Message msg) throws MessagingException;
}


public class IMAP implements MailReceiver<IMAPFolder, Long> {

private IMAPFolder imapInbox;

@Override
public Long getUID(Message msg) throws MessagingException {
return imapInbox.getUID(msg);
}

@Override
public void init(Folder inbox) {
imapInbox =  inbox;
}

@Override
public void doSomething(Long uid) {
// TODO Auto-generated method stub

}

}