【问题标题】:Do generic classes share static members? [duplicate]泛型类是否共享静态成员? [复制]
【发布时间】:2013-06-05 21:04:51
【问题描述】:

我想问一下泛型类。当我从一个泛型类创建两个对象实例时会发生什么。他们共享每个静态成员,还是都有自己的静态成员?

例如:

public A<?>(){
    public static Integer member = 0;
}

A<Integer> integer = new A<Integer>();
A<String> string = new A<String>();

IntegerStringmember 后面有相同的引用吗?

【问题讨论】:

  • 您的问题是有效的,但您发布的代码很糟糕:它既不是有效的构造函数,也不是类声明。您的问题的答案是:是的,它们共享每个静态成员。另外,您可以自己回答问题:System.out.println(integer.member == string.member);System.out.println(A.member == A.member); 相同,因为是static)
  • 测试不难...
  • 如果成员本身是通用的会发生什么?喜欢public class MyClass&lt;T&gt; { public static T member; }??
  • @RaviThapliyal:不会编译。
  • 当您懒得尝试代码时会发生这种情况...

标签: java generics static


【解决方案1】:
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 变量。

【讨论】:

  • +1 这个问题的好例子。同样值得注意的是integer.member++; 是不好的风格,风格检查器不鼓励这样的代码。 static 成员应始终以静态方式访问,即:A.member++;
  • 当您有疑问时,请测试它! :) +1
【解决方案2】:

好问题,但答案是:不,你不能这样做,原因很简单:一旦编译,就没有 A 或 A 这样的东西,只有 A 因为 向后兼容性 Java 使用泛型类型擦除的原因。

C# 等其他语言中,事情会如您所愿,因为 C# 是从一开始就使用泛型创建的。

【讨论】:

  • 感谢您提及 C#。我最初的想法来自一个 C# 示例。
  • 我处于类似情况:使用 Java 时很难回到 10 年前,但我相信它会填补空白。 :)
【解决方案3】:

没有代表任何参数化类型(如A&lt;Integer&gt;)的类文字(A&lt;Integer&gt;.classClass 实例)。原始版本总是只有一个A(即A.class),这是所有静态成员所属的那个。

这就是为什么你不会做类似A&lt;Integer&gt;.member 的事情,它应该始终是原始版本A.member(这是所有实例共享的(也是唯一的))。

您可以在此处阅读有关该主题的文章 - Is there one instances of a static field per instantiation of a generic type?

【讨论】:

    【解决方案4】:

    是的,他们会共享变量。关于静态类变量的规则不会根据泛型的使用而改变。所有实例共享一个静态类变量。

    【讨论】:

    • 这不应被视为理所当然。在 C++ 中,A&lt;Integer&gt;A&lt;String&gt; 将是具有不同静态数据成员的不同类。
    • @NicolaMusatti:这是java标签下的问题......
    • 确实如此。然而,Java 泛型受到 C++ 模板的启发,我认为指出差异很重要。
    • @NicolaMusatti 那么为什么您自己的答案中缺少这个? :)
    • 因为西蒙似乎理所当然地认为只有一个 A 级。我只是想指出,这对于 OP 来说可能不是不言而喻的
    【解决方案5】:

    它们都共享它们的静态属性,因为在运行时 A&lt;Integer&gt;A&lt;String&gt; 不是不同的类。

    【讨论】:

      【解决方案6】:

      您只需要认为泛型是用于编译目的。在运行时,A&lt;Integer&gt;A&lt;String&gt; 之间没有区别:它们都是A 的实例。因此静态成员对于您可以创建的任何实例都是通用的,而与您使用的类型无关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-27
        • 1970-01-01
        • 2010-11-04
        • 2011-03-27
        • 2011-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多