2010-11-18 113 views
3

對不起,標題: -/如何將非泛型類集成到泛型層次結構中?

我寫了一個計算器的解析器。它有效,但我不喜歡我的令牌層次結構。解析器應該不知道具體的數字類型,例如它應該雙人間,BigDecimal的等是可配置的所以我有一個通用的令牌接口

public interface Token<T> { } 

public class NumToken<T> { 
    private final value T; 
    ... 
} 

public class OperatorToken<T> { 
    ... 
} 

現在我的問題是如何處理的「結構性」令牌是無論數量型,例如相同括號和分隔符。通用參數不僅在這種情況下是無用的,它阻止我使用該類型的枚舉。然而,枚舉是非常有用的,例如它可以用在switch語句中。

現在我已經「解決」的問題呀:

public enum CharToken implements Token<Object> { 

    OPEN('('), 
    CLOSE(')'), 
    SEPARATOR(','), 
    EOL(';'); 

    private final char ch; 

    private CharToken(char ch) { 
     this.ch = ch; 
    } 
} 

這工作,但強迫我到處寫INT像List<Token<? super T>>解析器的東西,假設所有其他類型實際上Token<T>時我投了。我在這裏明確地使用類型系統來反對穀物:從類型理論的角度來看,我撞到了牆上,因爲Java沒有Scala中的「Nothing」這樣的「底部」類型(這將非常合適)。有更好的解決方案嗎?

[澄清]

T是預期數量型我解析器應該工作時,令牌的不是「內容」。例如。對於OperatorToken<T>我有一個方法calc(T op1, T op1)。而且我希望能夠通過T參數化整個解析器,所以它使用的所有令牌都需要相同的T(好吧,如果您不像我那樣作弊),因此CharToken implements Token<Character>不會很有用。

+0

不應該是'implements Token ' – Bozho 2010-11-18 08:59:14

+0

'Token'中的'T'做了什麼? – khachik 2010-11-18 09:01:37

回答

1

在JDK中使用(例如,在java.util.Collections.emptyList())的溶液,利用擦除 - 類型參數真的不存在,因爲你可能還記得 - 和類型參數推斷的方法:

@SuppressWarnings("unchecked") 
public enum CharToken implements Token { // Note: No type parameter specified! 

    OPEN('('), 
    CLOSE(')'), 
    SEPARATOR(','), 
    EOL(';'); 

    public static <T> Token<T> open(){ return OPEN; } 
    public static <T> Token<T> close(){ return CLOSE; } 
    public static <T> Token<T> separator(){ return SEPARATOR; } 
    public static <T> Token<T> eol(){ return EOL; } 

    private final char ch; 

    private CharToken(char ch) { 
     this.ch = ch; 
    } 
} 

// Usage: 
Token<BigDecimal> bdOpen = CharToken.open(); 
Token<Integer> intOpen = CharToken.open(); 

不非常漂亮,但至少很容易使用。 (爲了清潔的緣故,你可能希望將enum封裝在僅暴露泛型方法的類中)。

+0

謝謝。我這樣做了,而且效果很好。儘管如此,它感覺就像作弊... – Landei 2010-11-19 20:16:29

0

Java中有一個Void類型,用於類似用途。但是,IMO的類型參數應該是Character,正如Bozho所建議的那樣。