实用程序函数对Array类的正确签名:Comparable <E>或Comparable <?超级E>?

我正在尝试将实用函数写入Array类。

该函数应返回所有可比较类型的最小元素。

我的问题是函数应该具有哪个签名:

  1. public static <E> E min (Comparable**<E>**[] arr)
  2. public static <E> E min (Comparable**<? super E>**[] arr)

在Java中,数组是变量,这意味着如果B扩展了A,那么A []和B []也相关,但是ArrayList<A>ArrayList<B>没有相同的连接。

这是完整的代码:

@SuppressWarnings("unchecked")
public static <E> E min (Comparable<E>[] arr){

    E min= null;

    if(arr.length > 0)          
        min = (E) arr[0];

    for (int i = 1; i < arr.length; i++) {

        if( (arr[i].compareTo((E) min)) < 0)
            min = (E) arr[i];
    }

    return min; 
}

注释:我有两个类A实现Comparable A,而B扩展了A

当签名为Comparable<? super E>时,则呼叫(从主):

A aArr[] = new A[] {new A(1),new B(2),new B(-1)};
B bb = min(aArr);

是编译错误:cannoot convert from ...A to ... B,但是当min()的签名为Comparable<? super E>时,相同的调用就可以了。

谢谢

benxiaolai 回答:实用程序函数对Array类的正确签名:Comparable <E>或Comparable <?超级E>?

第二个签名起作用是因为A是类B的超类,而它适合通配符条件? super B

如果您希望函数返回任何可比较类型数组的最小值,则只需要。

public static <E extends Comparable<E>> min (E[] arr)

这将允许您使用该方法来操作所有类型为可比较类型的数组。在您的情况下,您希望A和B相关联。因此,您还应该允许您的方法采用类E及其超类的参数。但是,仅当您尝试将A强制转换为B时才需要,例如您的示例。这使您希望您的方法采用E的超类(因为A是B的超类)并且仍然返回E类型的值。

public static <E extends Comparable<? super E>> min (E[] arr)
,

IMO都不是此方法的“正确”签名。正确的签名是接受E[],其中E extends Comparable<? super E>

public static <E extends Comparable<? super E>> E min (E[] arr){

    E min= null;

    if(arr.length > 0)
        min = arr[0];

    for (int i = 1; i < arr.length; i++) {

        if( (arr[i].compareTo(min)) < 0)
            min = arr[i];
    }

    return min;
}

您当前的实现错误地假设“实现Comparable<T>的类必须是TT的子类”。这不一定是真的。这就是为什么您必须禁止显示这些警告的原因。

无论如何,回到您的实际问题。在主叫方,您正在做B bb = min(aArr)。在Comparable<E>情况下,由于编译器无法推断E应该是什么而出现错误。不能为A,因为不能将A分配给类型为B的变量。也不能是B,因为您给它的是A[],而不是Comparable<B>[]

当您将其更改为Comparable<? super E>时,E 现在可以为B。由于A[]Comparable<? super B>兼容。

但这仅以一种真正的“ hacky”方式起作用,因为从技术上讲,由于BE,并且将数组中的每个元素都强制转换为B,并且由于Java泛型被删除,这不会失败。

问题的根源实际上在B bb = min(aArr)行中。您可能会错误地假设aArr的最小值为B类型。你怎么这么确定也可能是A,对吧?使用上述我的解决方案,如果您确定结果为B,则需要将结果转换为B

B bb = (B)min(aArr);
本文链接:https://www.f2er.com/2800092.html

大家都在问