如果确实如此,问题是:
如果可以在方法名称后放置类型参数,可能会出现什么问题?
E.g:
import com.google.common.base.Predicate;
static import com.google.common.base.Predicates.alwaysTrue;
Predicate<SomeType> p = alwaysTrue<SomeType>();
更新
我知道你可以用这种方式传递类型参数:
Predicate<SomeType> p = Predicates.<SomeType>alwaysTrue();
答案 0 :(得分:1)
如果问题是Java设计师为什么设计这样的语法:我最好的猜测是因为方法名称有自己的命名空间与变量/字段名称分开,这意味着它是合法的使方法名称与变量或字段具有相同的名称,并且上下文确定正在使用哪个名称。因此:
x = myName;
查找名为myName
的变量或字段,而
x = myName(arg);
查找名为myName
的方法。左(
是告诉编译器查找方法而不是变量的东西。这样,即使myName
具有作为变量和方法的合法含义,编译器也可以接受这两个语句。
如果语法是类型参数在方法名称之后:
x = myName<T>(arg);
编译器会非常困惑。此表达式是变量myName
,后跟<
(小于)运算符,后跟一个名为T
的变量,后跟一个>
运算符,后跟一个在括号中表达?或者是带有类型参数的方法调用?可能是因为没有两种可能的解释(因为<
和>
在Java中的boolean
参数上不合法),但是设计师认为它是合理的会对编译器造成太大的负担,或者在所有情况下正确设计语言规则的负担太大。
P.S。只是为了让您了解可能导致什么样的头痛:第一项任务在Java中是合法的:
// instance members
int name1, name2, name3;
public <T> boolean name2(int argument) { ... }
// some statement later on in some method
boolean x = name1<name2>>(name3); // legal
boolean x = name1<name2<name4>>(name3); // would be legal syntax if type parameters appeared
// after method names
请注意,解释>>
的规则很特殊 - 它在类型上下文中被视为两个单独的>
个字符(因此您可以ArrayList<ArrayList<Integer>>
),但作为换班操作员。我不想成为编写编译器代码或语言规则的人,以确保两者都得到正确处理。
答案 1 :(得分:1)
我在这里看到两个不同的问题:
为什么需要参数化方法的类或对象?
public class Test {
private static <T> void staticMethod() {}
private <T> void method() {}
public Test() {
method(); // Works!
<Integer>method(); // Doesn't work!
this.<Integer>method(); // Works again!
}
public static void main(String[] args) {
staticMethod(); // Works!
<Integer>staticMethod(); // Doesn't work
Test.<Integer>staticMethod(); // Works again!
}
}
不幸的是我无法给出答案......
第二个问题:为什么方法类型参数放在方法之前(而不是类参数,在类之后)?
这里我确实有预感 - 其中一个问题是通用构造函数。通用构造函数可以像任何其他方法一样具有类型参数,并且这些参数可以独立于类类型参数:
public class Class<T> {
public <V>Class(V arg) {
}
public static void main(String[] args) {
new <Number>Class<Object>(0);
}
}
这是有效的语法,第一个类型参数是方法参数,第二个是类型参数。
需要有一种区分这些机制的机制,并且记住 - 由于向后兼容性,开发人员可能会忽略这两种机制!
我想不出任何其他方法,而不是将它们放在构造函数调用的不同方面。
我想象有一个类似的边缘情况模糊不清,参数化的方法在没有对象或类的情况下调用,但我现在无法想到。