【问题标题】:Why do classes that implement an interface not count as the same type as the interface in Java?为什么实现接口的类与Java中的接口不属于同一类型?
【发布时间】:2011-03-14 14:55:14
【问题描述】:

我有

out.load(output, transactions, columnHeaders, dataFormat);

其中load定义为:

public boolean load(String outputfile, List<Transaction> transactions, List<String> columnHeaders, String dataFormat);

String output = "";
String dataFormat = "";
ArrayList<ARTransaction> transactions = new ArrayList<ARTransaction>();
List<String> columnHeaders = null;

在哪里

ARTransaction implements Transaction

为什么transactions的类型有问题?

【问题讨论】:

    标签: java generics inheritance types


    【解决方案1】:
    public boolean load(String outputfile, List<? extends Transaction> transactions, List<String> columnHeaders, String dataFormat);
    

    或者只是将交易声明为List&lt;Transaction&gt;

    以下是您显然不能这样做的常见示例:

    List<String> list = new ArrayList<String>();
    List<Object> objList = list; //if this were possible
    objList.add(Integer.valueOf(5));
    String val = list.get(0);  //ClassCastException here
    System.out.println(val);
    

    【讨论】:

    • 啊。这解决了问题。对你们俩都有关系。您的意思是,如果我想在方法load 中将BRTransaction t 添加到transactions。这是有道理的:-p
    • 这是否意味着 Java 将在load 中将事务视为 List 类型?
    • 不,Java 会认为它是某个未知 Transaction 子类的 List。 load 将不知道这种情况下的实际类型。如果重要,请考虑在加载方法中添加类型参数 (T extends Transaction)。
    • 这很好。所以事务的类型实际上是动态变化(向上)的! 对吗?
    • 不,没有什么动态的。它通过编译时的类型擦除发生。
    【解决方案2】:

    将从ArrayList&lt;ARTransaction&gt; 转换为List&lt;Transaction&gt; 的逆变类型有困难。

    改用List&lt;? extends Transaction&gt;

    【讨论】:

      【解决方案3】:

      因为它可能不满足Liskov substitution principle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-08
        • 2021-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-11
        • 2011-05-16
        • 1970-01-01
        相关资源
        最近更新 更多