我正在编写通用类
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));
上编译时间错误?
答案 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)必须是标识符或包限定标识符。它不允许括号。