泛型类和静态泛型方法

时间:2013-10-28 12:41:33

标签: java generics

我正在编写通用类

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));上编译时间错误?

5 个答案:

答案 0 :(得分: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));

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

要么像这样使用

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

SomeClass.min(Arrays.asList(1, 2, 3));

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

如果您需要技术原因,那是因为您的方法调用表达式不是one of the forms that's allowed by the syntax。与您最接近的形式是TypeName . NonWildTypeArguments Identifier ( ArgumentListopt )。但TypeName(定义为here)必须是标识符或包限定标识符。它不允许括号。