我想问一下泛型类。当我从一个泛型类创建两个对象实例时会发生什么。他们共享每个静态成员,还是都有自己的静态成员?
例如:
public A<?>(){
public static Integer member = 0;
}
A<Integer> integer = new A<Integer>();
A<String> string = new A<String>();
两者Integer
都有String
相同的参考member
吗?
public class A<T>{
public static Integer member = 0;
public static void main(String[] args)
{
A<Integer> integer = new A<Integer>();
A<String> string = new A<String>();
integer.member++;
System.out.println(string.member);
}
}
输出
1
所以,是的,这两个实例共享相同的member
变量。
好问题,但答案是:不,你不能,原因很简单:一旦编译就没有 A<Integer> 或 A<String> 这样的东西,只有 A 因为出于向后兼容性的原因 Java 使用泛型类型擦除。
在C#等其他语言中,事情会按您的预期工作,因为 C# 是从泛型开始创建的。
没有代表任何参数化类型(如)的类文字(A<Integer>.class
或实例)。原始版本(即)始终只有一个,并且所有静态成员都属于该版本。Class
A<Integer>
A
A.class
这就是为什么你不会做类似的事情A<Integer>.member
,它应该始终是原始版本A.member
(这是所有实例共享的(也是唯一的)版本)。
您可以在此处阅读有关该主题的文章 -每个泛型类型的实例化是否有一个静态字段实例?.
是的,他们会共享变量。关于静态类变量的规则不会根据泛型的使用而改变。静态类变量由所有实例共享。
它们都共享它们的静态属性,因为在运行时A<Integer>
并且A<String>
不是不同的类。
您只需要认为泛型是用于编译目的。A<Integer>
在运行时,和没有区别A<String>
:它们都是A
. 因此,静态成员对于您可以创建的任何实例都是通用的,而与您使用的类型无关。