6

I would like to ask about generic classes. What happens when I create two object instance from a generic class. Do they share every static members, or both have it's own static members?

So for example:

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

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

Do both Integer and String have the same reference behind member?

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Quirin
  • 738
  • 1
  • 5
  • 15
  • 2
    Your question is valid, but the code you posted is bad: It's neither a valid constructor, nor a class declaration. The answer to your question is: Yes, they share every static member. Also, you could answer the question yourself: `System.out.println(integer.member == string.member);` Which is the same as `System.out.println(A.member == A.member);` because of being `static`) – jlordo Jun 05 '13 at 21:06
  • It's not difficult to test... – Bernhard Barker Jun 05 '13 at 21:09
  • What happens if member itself is generic? Like `public class MyClass { public static T member; }`?? – Ravi K Thapliyal Jun 05 '13 at 21:12
  • @RaviThapliyal: wouldn't compile. – jlordo Jun 05 '13 at 21:13
  • This is what happens when you're too lazy to just try the code... – Luiggi Mendoza Jun 05 '13 at 21:21
  • Sorry guys, it maybe seems to be laziness, but I would like to get some hints and confirmation about the topic. – Quirin Jun 05 '13 at 21:27
  • @Lucia - It is best not to "fix" the code within a *question* (even when it is obviously wrong), because it may obscure the problem that brought that person here in the first place. If you spot an error, leave a comment or post an answer. – Leigh Jun 05 '13 at 21:30

6 Answers6

11
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);
    }
}

Output

1

So, yes the two instances share the same member variable.

Petros Tsialiamanis
  • 2,718
  • 2
  • 23
  • 35
  • 2
    +1 Nice example for the question. Also noteworthy that `integer.member++;` is bad style, and stylecheckers discourage code like this. `static` members should always be accessed in a static manner, i.e.: `A.member++;`. – jlordo Jun 05 '13 at 21:16
  • When you're in doubt test it! :) +1 – Pragmateek Jun 05 '13 at 21:19
3

Good question but the anwser is: no you can't for a very simple reason: once compiled there is no such thing as A<Integer> or A<String>, only A because for backward compatibility reasons Java uses generics type-erasure.

In other languages like C# things would work as you expect because C# was created from start with generics.

Pragmateek
  • 13,174
  • 9
  • 74
  • 108
2

There is no class literal (A<Integer>.class or Class instance) that represent any of parameterized type (like A<Integer>). There will always be only one for the raw version A (i.e. A.class), and that's the one with whom all the static members belong.

That's why you won't do something like A<Integer>.member, it should always be the raw version A.member (and that is the one (and only) shared by all the instances).

You can read an article on the topic here - Is there one instances of a static field per instantiation of a generic type?.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

Yes, they would share the variable. The rules about static class variables don't change based on the use of Generics. A static class variable is shared by all instances.

Simon Curd
  • 790
  • 5
  • 12
0

They all share their static attributes because at runtime A<Integer> and A<String> are not distinct classes.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55
0

You just have to think that generics are for compilation purpose. At runtime, there is no difference between A<Integer> and A<String>: they are all instances of A. So static members are common to any instances you can create, without any regard to the type you are using.

eternay
  • 3,754
  • 2
  • 29
  • 27