Java 构造函数中的泛型推理
如果我有一个类Java 构造函数中的泛型推理,java,generics,Java,Generics,如果我有一个类Foo: public class Foo<T> { public Foo(T t) { //do something } public static <E> void bar(E e) { //do something } } 公共类Foo{ 公共食物(T){ //做点什么 } 公共静态空栏(E){ //做点什么 } } 为什么Foo.bar(“字符串”)推断E是一个字符串(因此不会抛
Foo
:
public class Foo<T> {
public Foo(T t) {
//do something
}
public static <E> void bar(E e) {
//do something
}
}
公共类Foo{
公共食物(T){
//做点什么
}
公共静态空栏(E){
//做点什么
}
}
为什么
Foo.bar(“字符串”)
推断E
是一个字符串(因此不会抛出编译器警告),但newfoo(“字符串”)
不能推断T
是字符串吗?我想你需要这样做
new Foo<String>("String");
newfoo(“字符串”);
告诉我们如何传递泛型信息;与Collections API类似。因为构造函数可以被视为一个特殊的实例方法,所以它不是类型化的-它从类名(带有类型参数)获取其类型,例如
Foo
。即构造函数未定义为:
public <T> Foo(T t) ...
publicfoo(T)。。。
也不可能。这样做会隐藏类的泛型类型(并且会得到警告)
然而,静态方法是类型化的。仅供参考,一旦推断出类型,泛型无参数调用相当于:
Foo.<String>bar("String");
Foo.bar(“字符串”);
看看这个,我想在这里猜一猜。考虑以下事项:
public class Foo {
public <E> Foo(E t) {
//do something
}
public static <E> void bar(E e) {
//do something
}
}
这是因为这里正在推断E
的类型。正如您在方法案例中所期望的那样。但是,您得到的错误不是因为没有推断参数类型,而是因为无法推断类的原始类型
我认为这归根结底是类原始类型可以传播到方法,但是方法不能使用推理设置类原始类型。当Java实现泛型时,决定了没有类型参数的泛型类实例化总是返回原始类型。这与缺少类型参数的泛型方法不同,编译器试图推断类型参数的类型。来自Java教程: 通常,Java编译器可以推断泛型方法调用的类型参数。因此,在大多数情况下,您不必指定它们 但当讨论转向施工人员时: 请注意,要在泛型类实例化期间利用自动类型推断,必须指定菱形。在以下示例中,编译器生成未检查的转换警告,因为HashMap()构造函数引用的是
HashMap
raw类型,而不是Map
类型:
Map myMap=newhashmap();//未经检查
转换警告
资料来源:
这在Java7中保持不变,但是他们试图通过支持菱形语法来减少重复性。例如,
Foo-Foo=new-Foo(“字符串”)
。见。@忽必烈汗的回答是正确的;newfoo
的类型为原始Foo
,用于向后兼容
Java7的构造函数菱形类型推断(newfoo)
)与方法上的方法类型推断相同,并根据方法类型推断定义
如果类实例创建表达式使用“”来省略类类型参数,则会定义方法m1…mk的列表,以用于重载解析和类型参数推断
…然后使用§15.12.2(确定方法签名)中描述的过程选择m1…mk中的一个
你的怀疑是正确的,构造器可以像方法一样使用推理,没有本质的区别。由于向后兼容性问题,您只需添加
为什么Java花了6年时间才添加此功能是另一回事。您看到的确切错误是什么?@linuxuser27您在
newfoo(“字符串”)上收到原始类型警告代码>这是正确的。OP不是问“需要做什么”,而是问“为什么”,因为在静态方法调用的事实上,这是不需要的当您已经将字符串
传递给构造函数时,code>似乎是重复的。我认为在Java 7中重复性会降低。在Java 7中,您可以这样做:ArrayList list=new ArrayList()代码>。类型是自动推断的。+1。非常有趣,但是我仍然不明白为什么在这个例子中,它不能通过类似的机制从参数列表中推断出来。你注意到了吗:如果你像这样声明你的类:class TestClass
和你的构造函数public TestClass(tt)
你不会得到警告,但是如果您这样做:classtestclass
和您的构造函数publictestclass(tt)
您会收到一条编译器警告,声明“类型参数T正在隐藏类型T”@Varun-Achar您可以声明,如果您在构造函数上重新声明,您确实在隐藏该类”。我相信Boehmian想说的是,因为我没有创建泛型构造函数,它是从类继承它的类型,而不是相反。但它仍然留下一个问题,为什么类不能从构造函数推断类型参数。我相信这就是Bohemian的意思。因为您没有声明类的类型参数,所以构造函数没有被赋予类型。@Jeffrey-我同意。这是一个很好的问题。谢谢
Foo f = new Foo("String");