从map <string,table <?=“”extends =“”entity =“”>&gt; </string,>获取带有未知泛型参数的对象

时间:2012-11-11 13:14:48

标签: java generics

我有

public class Entity

在哪个工作班上:

public class Table<Target extends Entity>
{
    public boolean save (Target target)
    public Target load (int id)
}

直到我将Table类的这些对象放在Database类Map中,一切正常,但是:

public class Database
{
    public String name;
    public Map<String, Table<? extends Entity>> tables = new HashMap <String, Table<? extends Entity>> ();
    public Context context;
    public int version;
    public Database (Context context, int version)
    {
        this.context = context;
        this.version = version;
    }
    public void add (Table<? extends Entity> table)
    {
        tables.put(table.name, table);
    }
    public Table <? extends Entity> table (String name)
    {
        return (Table<? extends Entity>) tables.get(name);
    }

}

假设我们有:

 public class Apple extends Entity

我希望此代码能够正常运行:

    //init      
    database = new Database(getBaseContext(), 4);
    new Table<Apple> (database, Apple.class);

    //this is where solution need occurs !
    database.table("apples").save (new Apple("green apple"));

该类型中的方法save(捕获#1-of?extends Entity) 表(捕获#1-of?扩展实体)  不适用于参数(注释)

如何使map.get方法有效?

2 个答案:

答案 0 :(得分:1)

要使这更方便,可以做的一件事是按目标类映射表:

Map<Class<? extends Entity>, Table<? extends Entity>> tables;

public void <T extends Entity> addTable(Class<T> cls, Table<T> table) {
    tables.put(cls, table);
    // alternately make it possible to get the target class from the table
}

@SuppressWarnings("unchecked")
public <T extends Entity> Table<T> getTable(Class<T> cls) {
    return (Table<T>) tables.get(cls);
}

正如注释所暗示的那样,这并不是所有类型都安全的 - 您需要确保永远不会使tables中的键和值不匹配。

答案 1 :(得分:0)

感谢用户millimoose我修改了数据库类:

public class Database
{
    public String name;
    public Map<Class<? extends Entity>, Table<? extends Entity>> tables = new HashMap <Class<? extends Entity>, Table<? extends Entity>> ();
    public Context context;
    public int version;
    public Database (Context context, String name, int version)
    {
        this.name = name;
        this.context = context;
        this.version = version;
    }

    public <Target extends Entity> void add (Class<Target> target, Table<Target> table) 
    {
        tables.put(target, table);
    }   

    @SuppressWarnings("unchecked")
    public <Target extends Entity> Table<Target> table (Class<Target> target) 
    {
        return (Table<Target>) tables.get (target);
    }   
}

之后可以像这样使用它:

    database = new Database(getBaseContext(),"notes", 1);
    database.add (Note.class, new Table<Note> (database, Note.class));


    database.table(Note.class).save (new Note("first note"));
    database.table(Note.class).save (new Note("second note"));
    database.table(Note.class).save (new Note("best note"));

    items.addAll(database.table(Note.class).load());    

似乎我还没有足够的技能知道它为什么有效,但在地图键解决问题中添加(Class(?extends Entity)。