This is a little tricky. You get an error if you try to compile this too:
You could argue that this should work, since you might do
StaticGenerics<Integer>.a = 10;
and the compiler should have no problem inferring T as being Integer. The problem is that somewhere else you might have
StaticGenerics<
String>.a = "Text";
Then you have a conflict.
You can have instance variables of type variable types, because each instance will be tied (like Vishwanath said) to a specific generic type, since you can't have an instance variable without having an instance of the class, and when the class is a parameterized type, it means you have provided a concrete type for the type variables, so the compiler can infer the concrete type for the type variable. But when you deal with static stuff the compiler can't do that and ensure there won't be conflicts.
In other words, for this generic type:
StaticGenerics<Integer> instances seem to get an Integer b member
StaticGenerics<String> instances seem to get a String b member
(notice I say "seem to get" and not "get" because in reality what they get is an Object b member due to type erasure, but as a part of type erasure the compiler will insert casts to the specific type as necessary.)
But
StaticGenerics<Integer> class can not get a static Integer a member
StaticGenerics<String> class can not get a static String a member
(the reason why this can't work is that static members are shared by all instances, and since you can have instances of more than one generic type, the compiler has no way of performing type erasure.)
What would happen if you set a like this:
StaticGenerics<Integer>. a = 10;
and then try to access it like this:
String = StaticGenerics<String>.a;