【问题标题】:Something different between array and generics数组和泛型之间的不同之处
【发布时间】:2013-12-09 02:04:17
【问题描述】:

刚看了《Effective Java》,看到一句话是这么说的

因此,数组提供运行时类型安全,但不提供编译时类型安全,泛型反之亦然

我不太清楚,即使在阅读了所有给出的示例后我也很困惑。谁能给我解释一下,谢谢一百万。

【问题讨论】:

    标签: java arrays generics


    【解决方案1】:

    您不能在运行时更改数组(引用)的类型。但是你可以编译尝试的代码就可以了。

    String[] strings = new String[1];
    Object[] objects = strings;
    objects[0] = new Integer(1); // RUN-TIME FAILURE
    

    当您编译您的应用程序时,编译器不会抛出任何错误。

    另一方面,如果您使用泛型,这将在您编译(构建)应用程序时给您一个错误。

    ArrayList<String> a = new ArrayList<String>();
    a.add(5); //Adding an integer to a String ArrayList - compile-time failure
    

    换句话说,您不需要实际运行您的应用程序并执行该部分代码来查找问题。

    请注意,编译时故障比运行时故障更可取,因为您在将问题发布给用户之前就发现了问题(之后为时已晚)!

    【讨论】:

      【解决方案2】:

      对于泛型集合,此代码尝试将整数放入字符串列表,在第二行给出编译时错误:Cannot cast from List&lt;String&gt; to List&lt;Object&gt;:

      List<String> listOfStrings = new ArrayList<>();
      List<Object> listAgain = (List<Object>)listOfStrings;
      listAgain.add(123);
      

      具有数组的等效代码可以完美编译,因为将 String 数组用作 Object 数组是合法的。 (从技术上讲,数组是covariant。)

      String[] arrayOfStrings = new String[10];
      Object[] arrayAgain = arrayOfStrings;
      arrayAgain[0] = 123;
      

      但是,如果它实际上包含整数,它就不是一个有效的字符串数组,因此在运行时会检查每个在其中存储内容的操作。在运行时它会以ArrayStoreException 爆炸。

      【讨论】:

      • 非常感谢,也是对我帮助很大的一个很好的例子。
      【解决方案3】:

      Java Array 提供协变返回类型,而泛型不提供协变返回类型。

      让我们通过简单的例子来理解

      public class GenericArrayDiff {
          public static void main(String[] args) {
              List<Vehicle> vehicleList = null;
              List<Car> carList =  null;
              Vehicle[] vehicleArrays;
              Car[] carArrays;
      
              // illegal
              carList = vehicleList;
              // illegal
              vehicleList = carList;
              // illegal
              carArrays = vehicleArrays;
              // legal because array provides covariant return type
              vehicleArrays = carArrays;
          }
      
      }
      class Vehicle {
      
      }
      class Car extends Vehicle {
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多