【问题标题】:collection of date using generics使用泛型收集日期
【发布时间】:2016-11-25 06:51:32
【问题描述】:

我正在阅读有关有效 Java 中的泛型第 23 条的内容。如下所述:

虽然可能会不小心将硬币插入邮票中 收藏可能显得牵强,问题却是实实在在的。例如, 很容易想象有人将 java.util.Date 实例放入 应该只包含 java.sql.Date 实例的集合。

我无法理解作者所说的“很容易想象有人将 java.util.Date 实例放入应该只包含 java.sql.Date 实例的集合中”是什么意思?

Collection<java.util.Date> dateColl = new ArrayList();
String strDate = "2011-12-31 00:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
java.util.Date date = sdf.parse(strDate);
java.sql.Date sqlDate = new Date(date.getTime());

dateColl.add(sqlDate);

为什么上面的代码没有抛出编译错误?

【问题讨论】:

  • 更好的问题:为什么你认为它应该是一个编译错误?
  • sorry last statement is wrong 它应该是 sqldate 而不是更正的日期。

标签: java generics effective-java


【解决方案1】:

我无法理解作者所说的“很容易 想象有人将 java.util.Date 实例放入集合中 应该只包含 java.sql.Date 实例”?

在你的例子中:

Collection<java.util.Date> dateColl = new ArrayList();
java.util.Date date = sdf.parse(strDate);
...
dateColl.add(date);

你做相反的事情。您声明了java.util.Date 的集合。此外,您还在java.util.Date instance 的集合中添加了一个java.util.Date 实例。您永远不会使用您声明的 java.sql.Date 实例,当然,在 java.util.Date 的集合中添加 java.util.Date 实例不需要任何类型转换,也不会质疑类型兼容性。

从 OOP 的角度来看:java.sql.Datejava.util.Date 类型。所以,这是合法的:

Collection<java.util.Date> dateColl = new ArrayList();
dateColl.add(new java.sql.Date(...));

要理解问题,你应该声明:

Collection<java.sql.Date> dateColl = new ArrayList();

然后尝试添加 java.util.Date 实例。在那里,您将遇到编译问题,因为“您将 java.util.Date 实例放入应该仅包含 java.sql.Date 实例的 集合” .

如果在 Collection 类中不使用泛型,编译不会失败,因此在运行时,如果您希望有一个仅包含 java.sql.Date 实例的集合,您可能会拥有 ClassCastException

在这里,您将有一个 ClassCastException 在循环中,因为您无法将 java.util.Date 实例转换为 java.sql.Date 实例:

Collection mySqlDates = new ArrayList();
mySqlDates.add(new java.sql.Date(...));
mySqlDates.add(new java.util.Date(...));

for (Object object : mySqlDates) {
    java.sql.Date sqlDate = (java.sql.Date) object; 
}

【讨论】:

    【解决方案2】:

    date 的类型为 java.util.Date,与您声明 Collection 的类型相同,因此没有错误。但是,java.sql.Date 确实扩展了 java.util.Date,因此您应该能够将这两个版本都存储在您的收藏中而不会出现问题。

    【讨论】:

      【解决方案3】:

      为什么上面的代码没有抛出编译错误?

      您的集合dateColl 的类型为java.util.Date,因此您可以添加任何java.util.Date 或其子类型的对象,如下所示:

      Collection<java.util.Date> dateColl = new ArrayList();
      String strDate = "2011-12-31 00:00:00";
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
      java.util.Date date = sdf.parse(strDate);
      java.sql.Date sqlDate = new Date(date.getTime());
      dateColl.add(date); //VALID
      dateColl.add(sqlDate);//VALID
      

      事实上,您可以添加java.sql.Date 对象以及如上所示(因为java.sql.Date extends (IS-A) java.util.Date

      【讨论】:

      • OP 正在将date 添加到集合中,这是一个Date 对象。不是你错了,你是看错了情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多