泛型-为什么类类型变量在静态上下文中无效



我正在从一本书中学习Java泛型。这本书说"类类型变量在静态上下文中无效",并用下面的例子进行了解释。

考虑一个具有类型变量的泛型类,例如Entry。不能将类型变量K和V与静态变量或方法一起使用。例如,以下内容不起作用:

public class Entry<K, V> {
// Compiler error - V in static context ("Entry.this' cannot be referenced from a static context")
private static V defaultValue;
// Compiler error - V in static context ("Entry.this' cannot be referenced from a static context")
public static void setDefault(V value) {
defaultValue = value;
}
}

毕竟,类型擦除意味着在被擦除的Entry类中只有一个这样的变量或方法,而不是每个K和V都有一个。

我不明白上面的解释。我也尝试为K创建相同的代码,但我得到了相同的编译错误。为什么上述代码是非法的?

让我们假设static变量确实按照您描述的方式工作。。。

我本来可以做的:

Entry<String, Integer>.defaultValue = 1;
Entry<String, String>.defaultValue = "Hello";
System.out.println(Entry<String, Integer>.defaultValue); // 1
System.out.println(Entry<String, String>.defaultValue); // Hello

这就是你所期望的,不是吗?

但请记住,static变量是每个类一个。由于类型擦除,Entry<String, Integer>Entry<String, String>被认为是同一类。对于上面的代码工作,1"Hello"需要存储在两个不同的地方(两个变量(!

V将是实例化类的类型。如果V的两个类实例化为不同的类型,那么哪种类型将用于访问由类级别的所有类共享的静态字段?

private static V defaultValue;

现在,一个实例化类将V作为String,而另一个则将V作为Long

但是static可用于所有类,那么访问时会是哪一个?

这与为什么不能从静态上下文引用实例字段有关。一旦进入静态上下文,将访问实例字段的哪个"实例"?它无法确定,因此不合法(也没有意义(。

Java泛型的设计者选择使用一种称为"类型擦除"的机制来实现它。这意味着像Entry<String,Integer>Entry<Integer,String>这样的通用专业化不作为单独的类存在。类型参数将被擦除。

Entry<String,Integer>Entry<Integer,String>中删除类型参数后,只剩下Entry类。

如果可能有一个像defaultValue这样的静态变量,那么Entry<String,Integer>.defaultValue应该是一个Integer。你会期望Entry<Integer,String>.defaultValue是一个字符串。但在类型擦除之后,只有一个Entry类,只有一个子defaultValue变量,现在必须是Integer和String。这是不可能的。这就是为什么不能有泛型类型的静态变量。

最新更新