Java,泛型启用对象列表的隐式和显式类型转换

Java,泛型启用对象列表的隐式和显式类型转换,java,generics,Java,Generics,在使用Java和数据库时,我总是想知道一件事。我使用数据库抽象层,得到如下结果: Hashtable h = connection.selectRow("select * from table where id = 5"); connection = new yourConnectionClass<String>(); 但是,当以相同格式返回多行时,它将返回以下内容: ArrayList<Hashtable> a = connection.selectAll("sel

在使用Java和数据库时,我总是想知道一件事。我使用数据库抽象层,得到如下结果:

Hashtable h = connection.selectRow("select * from table where id = 5");
connection = new yourConnectionClass<String>();
但是,当以相同格式返回多行时,它将返回以下内容:

ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
ArrayList a=connection.selectAll(“从id>5的表中选择*);
现在,由于我喜欢泛型,我想通过使用

ArrayList<Hashtable<String,String>> a = connection.selectAll("select * from table where id > 5");
ArrayList a=connection.selectAll(“从id>5的表中选择*);
但这不会编译:

Cannot convert from ArrayList<Hashtable> to ArrayList<Hashtable<String,String>>.
无法从ArrayList转换为ArrayList。
然而,像这样分开,它是有效的:

ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
Hashtable<String,String> h = a.get(0);
ArrayList a=connection.selectAll(“从id>5的表中选择*);
哈希表h=a.get(0);
这只会产生类型安全警告:

Type safety: The expression of type Hashtable needs unchecked conversion to conform to Hashtable<String,String>.
类型安全性:Hashtable类型的表达式需要未经检查的转换才能符合Hashtable。
上面的一步似乎与这里的两行操作相同,但是混搭成一个Java拒绝进行转换。我怀疑是某种内部机制造成了这种行为,但还没有找到原因

有人愿意详细说明一下吗

编辑:只是澄清一下。在我的示例中,错误消息说

Cannot convert from ArrayList<Hashtable> to ArrayList<Hashtable<String,String>>.
无法从ArrayList转换为ArrayList。
在下面的几行中,Java似乎非常有能力完成它刚刚告诉我的在我使用Java时无法完成的事情

Hashtable<String,String> h = a.get(0);
Hashtable h=a.get(0);

在我看来,Java在骗我。当然,不是故意的,我们喜欢彼此。但一定有原因。这正是我想要找出的。

这里有多个问题/缺陷

  • 哈希表是同步的。除非确实需要同步映射,否则不建议使用哈希表。您可以改为使用
    Collections.synchronizedMap

  • 您的实体模型是错误的。地图数据结构不应用于此类操作。相反,您应该为每个表创建一个实体。如果该表是关于Employee的,则创建一个名为Employee的类,该类具有映射到数据库中的列的不同属性

  • connection.select*
    方法似乎没有泛型化,这意味着您不能只在方法调用的左侧使用泛型

  • 总之,创建
    连接
    对象实例的类是不正确的


  • connection.selectAll()
    的返回类型是
    ArrayList
    。这就是必须在左边的东西

    因此,当你说

    ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
    Hashtable<String,String> h = a.get(0);
    
    ArrayList a=connection.selectAll(“从id>5的表中选择*);
    哈希表h=a.get(0);
    

    你会得到警告
    a.get(0)
    正在返回一个
    Hashtable
    (非泛型),您正在将其分配给
    Hashtable

    作为一种临时解决方案,我认为您可以像

    public class yourConnectionClass<E>
    
    公共类yourConnectionClass
    
    在该类中,您可以更改方法的Returntyoe:

    public <E> HashMap<E,E> selectAll()
    
    public HashMap selectAll()
    
    如果现在创建类的对象,如下所示:

    Hashtable h = connection.selectRow("select * from table where id = 5");
    
    connection = new yourConnectionClass<String>();
    
    connection=newyourconnectionclass();
    
    我认为这应该是可行的,因此方法的returntype现在应该是
    Hashmap

    我真的希望这能有所帮助。

    Vector
    Vector
    的赋值是不安全的(因为原始向量可能具有不同的元素类型),但仍然允许使用未经检查的转换(§5.1.9),以便能够与遗留代码进行接口


    原始型支架是半成品;类似这样的一些简单例子可以简化转换。

    您能告诉我您的
    连接
    对象是哪个类吗?它是来自我们的数据抽象层的一个类,实现了selectAll()、selectRow()和selectColumn()方法,返回类型敏感(分别为ArrayList、Hashtable和ArrayList)谢谢。我很清楚这种数据抽象方法的问题。它不是我的,我只是能在它坏的时候修复它,直到我们能用一个真正的解决方案来替换它。啊,好吧:)那样的话,恐怕你没有太多的灵活性。