2016-11-12 60 views
1

我很难创建CodeService接口的实现类。如何将类类型用作映射键和类的值列表作为映射值?

public interface CodeService<T extends AbstractCode> { 
    Map<Class<T>, List<T>> getCodes(); 
} 

AbstractCode是我的国家,城市和它在我的数据库中的相应表名性别类的抽象超类。

getCodes()方法应该返回类型为键的映射(Country.class,City.class,Sex.class)和由数据库返回的所有国家,城市和性别的列表作为值。

我的getCodes()方法的实现如下:

public class HibernateCodeService<T extends AbstractCode> implements CodeService<T> { 
    private Map<Class<T>, List<T>> map = new HashMap<Class<T>, List<T>>(); 

    public Map<Class<T>, List<T>> getCodes() { 

     /* Create an instance of the HibernateCodeDao<Sex> class */ 
     CodeDao<Sex> sexDao = new HibernateCodeDao<Sex>(); 

     /* Set the class type as Sex.class */ 
     Class<Sex> type = Sex.class; 

     /* Fetch all the sex values from the database */ 
     List<Sex> list = sexDao.fetchAll(Sex.class); 

     /* Put the Sex.class as the map key, list of sexes as the value */ 
     map.put(type, list); 

     /* Same code for Country and City classes */ 

     return map; 
    } 
} 

但是,IDE的map.put(type, list)行发出错误。

put (java.lang.Class<T>, java.util.List<T>) in Map cannot be applied to (java.lang.Class<Sex>, java.util.List<Sex>)

我的问题是,我怎么能存储类类型作为关键的IM我的地图,这样我可以获取这个类的所有值的列表?

+0

对于这是值得的,这是一个有趣的仿制药练习,但作为一个实际操作,至少是非常有问题的。 – chrylis

回答

1

如果我要实例化一个HibernateCodeService<Country>的实例,那么您的地图将通过您的参数为Map<Class<Country>, List<Country>>。由于CountrySex不相关,这意味着它不允许插入到您的地图中。

现在,对于您要完成的任务,您对泛型的使用将不起作用。因为你的地图的关键是Class<T>,这意味着你的地图每个实例只能包含一个可能的值,这有点会破坏你的地图的目的。虽然我与@chrylis,这是不是在生产制做一件好事同意,你就可以完成你打算从你的接口消除仿制药完成什么,和你的方法的返回:

public interface CodeService { 
    Map<Class<? extends AbstractCode>, List<? extends AbstractCode>> getCodes(); 
} 
+0

谢谢你的回答,这是一个我不得不创建的实践项目,所以除了更好地了解泛型外,并没有任何用处。 :)另外,你能解释为什么这不适合现实生活中的项目吗? – Kuyss

+1

对于现实生活中的系统而言,这有两个原因。首先,从接口名称不清楚特定实现支持哪些类类型,哪些不支持。在'AbstractCode'下创建新的子类很快就会变得非常混乱。其次,涉及投射的任何事情(必须由该方法的用户完成)通常是一种冒险的举动。理想情况下,您的界面应该为其支持的每种返回类型提供单一方法。 –

+0

关于第二点,实现此接口的正确方法是为每个扩展AbstractCode的类提供一个方法,并返回该特定类的值列表? – Kuyss