在使用Java和数据库时,我总是想知道一件事。我使用数据库抽象层并得到我的结果:
Hashtable h = connection.selectRow("select * from table where id = 5");
但是,当以相同的格式返回多个行时,它会返回:
ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
现在,因为我喜欢泛型,我想通过使用
来充分利用它ArrayList<Hashtable<String,String>> a = connection.selectAll("select * from table where id > 5");
但这不会编译:
Cannot convert from ArrayList<Hashtable> to ArrayList<Hashtable<String,String>>.
然而,像这样分开,它起作用:
ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
Hashtable<String,String> h = a.get(0);
这只会产生类型安全警告:
Type safety: The expression of type Hashtable needs unchecked conversion to conform to Hashtable<String,String>.
似乎上面的这一步与这两行相同,但是将它们混合成一个Java拒绝进行转换。我怀疑有一些内部机制负责这种行为,但尚未找到原因。
有人愿意详细说明吗?
编辑:只是为了澄清。在我的示例中,错误消息显示
Cannot convert from ArrayList<Hashtable> to ArrayList<Hashtable<String,String>>.
当在下面的行中时,Java似乎非常有能力它只是告诉我它在我使用时无法做到
Hashtable<String,String> h = a.get(0);
在我看来,Java对我说谎。当然,不是故意的,我们彼此喜欢。但必须有一个理由。这就是我想要找到的。
答案 0 :(得分:1)
connection.selectAll()
的返回类型为ArrayList<Hashtable>
。这就是左侧必须要做的事情。
因此,当你说
时ArrayList<Hashtable> a = connection.selectAll("select * from table where id > 5");
Hashtable<String,String> h = a.get(0);
你收到警告。 a.get(0)
正在返回Hashtable
(非通用),您将其分配给Hashtable<String,String>
。
答案 1 :(得分:0)
这里存在多个问题/缺陷。
Hashtable已同步。除非确实需要同步映射,否则不建议使用Hashtables。您可以改为使用Collections.synchronizedMap
。
您的实体型号错误。不应将Map数据结构用于此类操作。相反,您应该为每个表创建一个实体。如果表是关于员工的,则创建一个名为Employee的类,其中不同的属性映射到数据库中的列。
connection.select*
方法似乎没有通用化,这意味着您不能只在方法调用的左侧使用泛型。
总而言之,创建connection
个对象实例的类是不对的。
答案 2 :(得分:0)
作为临时解决方案,我认为您实际上可以输入类似
的类public class yourConnectionClass<E>
在该课程中,您可以更改方法的Returntyoe:
public <E> HashMap<E,E> selectAll()
如果您现在创建类的对象:
connection = new yourConnectionClass<String>();
我认为这应该有效,以便该方法的返回类型现在应该是Hashmap<String,String>
我真的希望有所帮助。
答案 3 :(得分:0)
http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.8
从
Vector
到Vector<String>
的分配是不安全的(因为原始向量可能具有不同的元素类型),但仍然允许使用未经检查的转换(第5.1.9节)以启用接口遗留代码
原始类型的支持是半生的;像这样的一些简单案例可以轻松过渡。