在这个简化的例子中,我有一个泛型类,以及一个返回Map而不管类型参数的方法.当我没有在包含类上指定类型时,为什么编译器会清除地图上的类型?
import java.util.Map;
public class MyClass<T>
{
public Map<String, String> getMap()
{
return null;
}
public void test()
{
MyClass<Object> success = new MyClass<Object>();
String s = success.getMap().get("");
MyClass unchecked = new MyClass();
Map<String, String> map = unchecked.getMap(); // Unchecked warning, why?
String s2 = map.get("");
MyClass fail = new MyClass();
String s3 = fail.getMap().get(""); // Compiler error, why?
}
}
Run Code Online (Sandbox Code Playgroud)
我得到这个编译错误.
MyClass.java:20: incompatible types
found : java.lang.Object
required: java.lang.String
String s3 = fail.getMap().get(""); // Compiler error
Run Code Online (Sandbox Code Playgroud) 这是一个问题,第一个代码清单编译得很好(JDK 1.6 | JDK 1.7):
ArrayList<String> a = new ArrayList<String>();
String[] s = a.toArray(new String[0]);
Run Code Online (Sandbox Code Playgroud)
但是,如果我将List
引用声明为原始类型:
ArrayList a = new ArrayList();
String[] s = a.toArray(new String[0]);
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误,说明String[]
是必需的,但是Object[]
找到了.
这意味着我的编译器将泛型方法解释为返回,Object[]
尽管String[]
它接收了一个as参数.
我加倍检查了toArray(myArray)
方法签名:
<T> T[] toArray(T[] a);
Run Code Online (Sandbox Code Playgroud)
因此,它是一个参数化方法,其类型参数<T>
与List(即<E>
)的类型参数无关.
我不知道在这里使用原始类型如何影响使用独立类型参数的参数化方法的评估.
为什么与模板类无关的集合会丢弃其类型?这是一个例子:(抱歉,由于我对此感到困惑而无法编译.)
package test;
import java.util.ArrayList;
import java.util.List;
public class TemplateTest {
public static class A { }
public static class B<T extends Comparable> {
List<A> aList = new ArrayList<A>();
public List<A> getAList() {
return aList;
}
public int compare(T t, T t1) {
return t.compareTo(t1);
}
}
public static void main(String[] args) {
B b = new B();
for (A a : b.getAList()) { //THIS DOES NOT WORK
}
List<A> aList = b.getAList(); //THIS WORKS
for (A a : aList) …
Run Code Online (Sandbox Code Playgroud) 我在调用具有显式类型参数的泛型方法时遇到编译器错误,就好像未考虑显式类型参数一样。最小的例子:
class CastExample {
static class ThingProducer<S> {
public <T> T getThing() { return null; }
}
static class ThingA {}
public static void main(String... args) {
ThingProducer thingProducer = new ThingProducer();
ThingA thingA = thingProducer.<ThingA>getThing(); // compile error here
}
}
Run Code Online (Sandbox Code Playgroud)
ThingProducer
是原始类型,因为类有一个类型参数,但在调用时getThing
我们不是引用类类型参数,而是提供方法类型参数。根据我对 JLS 的理解,这应该是合法的,但它给了我这个错误:
incompatible types: Object cannot be converted to ThingA
Run Code Online (Sandbox Code Playgroud)
如果我,错误就会消失
<S>
从ThingProducer
getThing
静态thingProducer ThingProducer<?>
而不是原始类型ThingProducer
这是编译器错误吗?如果不是,JLS 中的什么规则定义了这种行为?
请按顺序阅读代码中的注释,问题详情如下.
为什么会发生这种差异?
如果可能,请引用JLS.
import java.util.*;
/**
* Suppose I have a generic class
* @param <T> with a type argument.
*/
class Generic<T> {
// Apart from using T normally,
T paramMethod() { return null; }
// the class' interface also contains Generic Java Collections
// which are not using T, but unrelated types.
List<Integer> unrelatedMethod() { return null; }
}
@SuppressWarnings("unused")
public class Test {
// If I use the class properly (with qualified type arguments)
void properUsage() { …
Run Code Online (Sandbox Code Playgroud) 今天我遇到了javac
关于泛型类型推理的奇怪行为.这是用于说明这种奇怪行为的示例类:
import java.util.Map;
import java.util.Collections;
import java.util.HashMap;
public class Test {
protected <T> T strange(T t, Map<String, String> map) {
return t;
}
protected void ok(Map<String, String> map) {}
protected <T> T test(T t) {
T res = strange(t , new HashMap<String, String>());
//Doesn't work
//res = strange(t, new <String, String>HashMap());
ok(new <String, String>HashMap());
res = strange(t, Collections.<String, String>emptyMap());
//Doesn't work
//res = strange(t, Collections.EMPTY_MAP);
res = strange(t, (Map<String, String>) Collections.EMPTY_MAP);
ok(Collections.EMPTY_MAP);
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
注意//Doesn't …