4

我正在写通用类

public class SomeClass<T> {

    public static <T extends Comparable<? super T>> T min(Collection<? extends T> c) {
        T min = c.iterator().next();
        for (T element : c)
            if (element.compareTo(min) < 0)
                min = element;
        return min;
    }

}

public class Main {

    public static void main(String[] args) {
        SomeClass<Integer>.min(Arrays.asList(1, 2, 3)); // compile-time error
        SomeClass.min(Arrays.asList(1, 2, 3)); // ok
    }

}

在泛型类SomeClass和泛型方法中,SomeMethod类型参数T是相同还是不同?

为什么我们在字符串上有编译时间错误SomeClass<Integer>.min(Arrays.asList(1,2,3));

4

5 回答 5

3

类声明

public class SomeClass<T> 

定义一个泛型类,其中<T>指定类型参数(也称为类型变量)。这引入了类型变量 ,T它可以在类中的任何地方使用。

以及方法声明:

public static <T extends Comparable<? super T>> T min(Collection<? extends T> c) {
...
}

定义一个generic method. 泛型方法是引入自己的类型参数的方法。这类似于声明泛型类型,但类型参数的范围仅限于声明它的方法。

现在如果你想调用泛型方法min,你需要调用:

SomeClass.<Integer>min(Arrays.asList(1,2,3));
于 2013-10-28T12:55:36.043 回答
0

这是不同的,你不应该写这样的代码,特别是因为可能会造成混淆。始终在这些类中的类和方法上使用不同的类型变量。

于 2013-10-28T12:44:41.437 回答
0

T 代表类型,您正在访问与 T 无关的静态方法。

要么像这样使用

SomeClass<Integer> a = new SomeClass<Integer>();
a.min(Arrays.asList(1, 2, 3));

或者

SomeClass.min(Arrays.asList(1, 2, 3));
于 2013-10-28T12:56:42.873 回答
0

这两个T是不同的:第一个是类的参数(并且未使用),第二个是特定于方法的。由于该方法是静态的,因此类参数不会影响它。

当您编写 时SomeClass<Integer>.min(Arrays.asList(1, 2, 3));,您会收到一个错误,因为添加参数没有意义,SomeClass因为没有实例化该类的对象。SomeClass仅用于告诉编译器您要从该类调用静态方法。您可以使用 向方法添加参数SomeClass.<Integer>min(Arrays.asList(1, 2, 3));,但您不必这样做,因为编译器可以在此处推断类型。

于 2013-10-28T13:20:19.127 回答
0

所以编译消息告诉你的是它是一个语法错误。为什么它是无效的语法很容易理解。您正在尝试调用类型的方法。这意味着您正在调用静态方法。静态方法不在泛型类型参数的范围内。因此,不允许将泛型类型参数放在左侧。

如果您想要技术原因,那是因为您的方法调用表达式不是syntax 允许的形式之一。最接近您的形式是TypeName . NonWildTypeArguments Identifier ( ArgumentListopt ). 但是(在此处TypeName定义)必须是标识符或包限定标识符。它不允许使用括号。

于 2013-10-28T21:32:55.507 回答