2017-02-20 80 views
2

以下是一個清理過的示例,旨在將其減少爲單個問題。有3個類文件(在那裏有幾個類的shell)。不起作用的是在SpanTable類中的getTable()getCreateTableList()中的每一個上的第一個參數。我想知道如何獲得該參數以使其原始Span/SpanTable子類型並傳入DbTable調用?或者真的,DbTable不需要額外的信息,但我希望SpanTable或任何調用者保留它的類型。帶有泛型子類的Java(以及靜態方法)

DbRow:

public class DbRow { 
    static class Span extends DbRow {} 
} 

DBTABLE:

import java.util.ArrayList; 

abstract public class DbTable<R extends DbRow> { 

    static class PairList<L, R> { 
     public void addEntry(L s, R t) { } 
     public R getRightForLeft(L left) { return null; } 
    } 
    static class DbPlatform { } 
    static class DbSelectStatement { } 
    public static class Span extends DbRow { } 
    static class TableList<R extends DbRow, T extends DbTable<R>> extends ArrayList<T> {} 
    static class PlatformTableList<R extends DbRow, T extends DbTable<R>> 
        extends PairList<DbPlatform, TableList<R, T>> {} 
    static DbSelectStatement getDefaultQuery(String tableName) { return null; } 

    public DbTable(DbPlatform platform, String tableName) { } 
    public DbSelectStatement getStatement() { return null; } 

    /** Return the matching DbTable with matching DbSelectStatement or null */ 
    static protected DbTable<DbRow> getTable(
      PlatformTableList<DbRow, DbTable<DbRow>> platformList, 
      DbPlatform platform, DbSelectStatement stmt) { 
     // Get the table from the list, or create new 
     TableList<DbRow, DbTable<DbRow>> list = 
       getCreateTableList(
       (PlatformTableList<DbRow, DbTable<DbRow>>) platformList, platform); 
     // Search the list for a match 
     for(DbTable<DbRow> table : list) 
      if(table.getStatement().equals(stmt)) 
       return table; 
     return null; 
    } 

    /** Get or create and return a TableList for the Platform. */ 
    static protected TableList<DbRow, DbTable<DbRow>> getCreateTableList(
      PlatformTableList<DbRow, DbTable<DbRow>> platformList, DbPlatform platform) { 

     TableList<DbRow, DbTable<DbRow>> list = (TableList<DbRow, DbTable<DbRow>>) 
       platformList.getRightForLeft(platform); 
     if(list == null) { 
      list = new TableList<DbRow, DbTable<DbRow>>(); 
      platformList.addEntry(platform, list); 
     } 
     return list; 
    } 
} 

SpanTable:

class SpanTable<R extends DbTable.Span> extends DbTable<R> { 

    static private PlatformTableList<Span, SpanTable<Span>> platformList = 
      new PlatformTableList<Span, SpanTable<Span>>(); 

    static public SpanTable<Span> getCreateSpanTable(DbPlatform platform, String tableName) { 

     SpanTable<Span> table = (SpanTable<Span>) getTable(platformList, platform, 
       getDefaultQuery(tableName)); 
     if(table == null) { 
      table = new SpanTable<Span>(platform, tableName); 
      getCreateTableList(platformList, platform).add(table); 
     } 
     return table; 
    } 

    private SpanTable(DbPlatform platform, String tableName) { 
     super(platform, tableName); 
    } 
} 
+0

由於我不能編譯,我不能確切地告訴問題是什麼。您能否將問題重寫爲可編譯狀態?我的意思是,它不是像「我爲什麼不能編譯」這樣的問題,它的問題是「我爲什麼要使用」。 –

+1

@PeterRader現在組織成3個類文件。 –

+1

@MarkMeyers你不能說'class TableList > extends ArrayList > {}'因爲你必須首先列出所有的類型變量。做到這一點的方法是:'class TableList >擴展ArrayList >' –

回答

1

您可以DbTable類內的工廠方法通用的,所以他們持有的特定表鍵入(T)通過平臺列表傳遞給他們:

abstract public class DbTable<R extends DbRow> { 

    protected DbTable(DbPlatform platform, String tableName) { } 

    static class TableList<T extends DbTable<?>> extends ArrayList<T> {} 

    static class PlatformTableList<T extends DbTable<?>> 
        extends PairList<DbPlatform, TableList<T>> {} 

    /** Return the matching DbTable with matching DbSelectStatement or null. 
    * Will create/add a new TableList if platform not found. */ 

    static protected <T extends DbTable<?>> T getTable(PlatformTableList<T> platformList, 
      DbPlatform platform, DbSelectStatement stmt) { 

     // Get the table from the list, or create new 
     TableList<T> list = getCreateTableList(platformList, platform); 
     // Search the list for a match 
     for(T table : list) { 
      if(table.equals(stmt)) 
       return table; 
     } 
     return null; 
    } 

    /** Get or create and return a TableList for the Platform. */ 
    static protected <T extends DbTable<?>> TableList<T> getCreateTableList(
      PlatformTableList<T> platformList, DbPlatform platform) { 

     TableList<T> list = platformList.getRightForLeft(platform); 
     if(list == null) { 
      list = new TableList<T>(); 
      platformList.addEntry(platform, list);    
     } 
     return list; 
    } 

} 

現在你也可以去掉投在你getCreateSpanTable()方法:

SpanTable<Span> table = getTable(platformList, platform, 
       getDefaultQuery(tableName)); 

正如評論指出:如果你想保存特定行類型RTableList類,你可以寫class TableList<R extends DbRow, T extends DbTable<R>> extends ArrayList<T> {}此外,我會盡量避免延伸ArrayList並創建一個字段,而不是ArrayList

+0

謝謝。這很好。我很好奇你爲什麼要避免擴展'ArrayList'? –

+0

@MarkMeyers一般來說,當談到使用集合時,我會比繼承組合優於繼承(這裏是http://stackoverflow.com/q/4779173)。但是,它當然取決於。有時候,(也可能是你的情況),擴展'ArrayList'就像[這裏](http://stackoverflow.com/a/8098644)所示是有意義的。 – Calculator