调用其参数以交集类型为界的方法

Ant*_*ues 6 java generics

静态方法的上下文中,我想缩小类型引用并为这样的对象调用更具体的方法:

public static <T, L extends List<? extends T> & RandomAccess> void do(L list) {
    // Do some stuff
}

public static <T> void do(Iterable<? extends T> iterable) {
    if(iterable instanceof List && iterable instanceof RandomAccess)
        // invoke do(List&RandomAccess) method
    else
        // do something else
}
Run Code Online (Sandbox Code Playgroud)


所以我想知道是否有一种语法允许调用do(Iterable)而不是使用像这样的一些hack:

private static <L extends List<? extends T> & Comparable> L cast(Iterable<? extends T> iterable) {
    return (L) iterable;
}

public static <T> void do(Iterable<? extends T> iterable) {
    if(iterable instanceof List && iterable instanceof RandomAccess)
        do(cast(iterable));
    else
        // do something else
Run Code Online (Sandbox Code Playgroud)


注意: 我知道不可能以这种方式强制转换我的迭代

do((List<? extends T> & RandomAccess) iterable);
Run Code Online (Sandbox Code Playgroud)

它在我身上找到了L in 的擦除

L extends List<? extends T> & Comparable
Run Code Online (Sandbox Code Playgroud)

List<? extends T>
Run Code Online (Sandbox Code Playgroud)


那么为什么我不能这样调用方法呢?

do((List<? extends T>) iterable); // Which results in invoking do(Iterable<? extends T)
Run Code Online (Sandbox Code Playgroud)

Boh*_*ian 2

您的假设是正确的:交叉点的擦除是第一种类型 - 即List(出于反射等目的)。

您可以通过提供要转换为方法类型的交集类型来编译代码,而无需“黑客”:

public static <T, L extends List<? extends T> & RandomAccess> void method(L list) {
    // do whatever
}

@SuppressWarnings("unchecked") // needed to suppress unsafe cast warning 
public static <T, L extends List<? extends T> & RandomAccess> void method(Iterable<? extends T> iterable) {
    if(iterable instanceof List && iterable instanceof RandomAccess)
        method((L)iterable); // calls the other method
    else
        return; // do whatever
}
Run Code Online (Sandbox Code Playgroud)

此代码将编译,第二个方法将根据需要调用第一个方法。

如果没有这种技术,就无法投射到交叉路口。


请注意,您的代码无法编译,因为do是 java 关键字,因此不是有效的方法名称。我用method()它来获取一个可编译的示例。

另外我认为你的意思是RandomAccess你编码的地方Comparable