添加类类型参数而不破坏客户端代码

时间:2017-03-12 15:01:40

标签: java generics maintenance raw-types

我正在尝试将类型参数添加到旧API的类中。由于Java泛型的一个特性,我遇到了一个问题,似乎会​​导致很多客户端代码停止编译。

我有一个这样的课程,我想将类型参数添加到:

class C {
    List<String> getStrings() {
        return Arrays.asList("dummy"); // Dummy implementation
    }

    Object getContent() {
        // Dummy implementation. In reality an object of 
        // some specific type is returned.
        return null; 
    }
}

请注意,getStrings的返回值是指定了成员类型的列表。

类型参数C成瘾之后会是这样的:

class C<T> {
    List<String> getStrings() {
        return Arrays.asList("dummy");
    }

    T getContent() {
        return null; 
    }
}

问题。客户端使用类C,如下所示:

class U {
    static void m() {
        // This compiles and works fine both before and after the 
        // type parameter is added.
        C c = new C();

        // ...

        // This also compiles and works fine both before and after the 
        // type parameter is added.
        Object cont = c.getContent();

        // But this doesn't type check any more! Since c now has a raw type
        // the return value of getStrings also has a raw type. So there
        // will be a 'can't assign Object to String' error.
        String s = c.getStrings().get(0);

    }
}

对于客户来说,问题的解决方案很简单:只需将无界通配符类型添加到C

C<?> c = new C<>();

但是这个API有很多外部客户端。如果使用C所有代码必须更新(即使是以微不足道的方式)来进行编译,这将是一个很大的不便。

有没有办法解决这个问题?有没有办法让我在类C中添加类型参数而不会破坏API的所有客户端的构建?

已经讨论了Java的泛型的相同机制,例如hereherehere,但他们不讨论解决方案和解决方法。

1 个答案:

答案 0 :(得分:1)

变通方法建议:您可以创建一个新类CV2(可以扩展或不扩展现有类C),提供新接口。

旧客户端可以继续使用旧类,新客户端可以使用新版本。当然,您将C注释为已弃用。