2013-06-05 2 views
5

Я хотел бы спросить об общих классах. Что происходит, когда я создаю экземпляр объекта из универсального класса. Разделяют ли они все статические члены, или оба имеют свои собственные статические члены?Разделяют ли общие классы статические члены?

Так, например:

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

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

Integer ли как и String имеют ту же ссылку за member?

+2

Ваш вопрос действителен, но код, который вы опубликовали, плохо: он не является ни конструктором, ни объявлением класса. Ответ на ваш вопрос: Да, они разделяют каждый статический член. Кроме того, вы можете сами ответить на вопрос: 'System.out.println (integer.member == string.member);' То же, что и 'System.out.println (A.member == A.member);' из-за 'static') – jlordo

+0

Это не сложно проверить ... – Dukeling

+0

Что произойдет, если сам член является общим? Подобно 'public class MyClass {public static T member; } '?? –

ответ

10
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 переменных.

+2

+1 Хороший пример для вопроса. Также следует отметить, что 'integer.member ++;' - это плохой стиль, а стилисты исключают такой код. Элементы 'static' всегда должны быть доступны статическим образом, т. е .:' A.member ++; '. – jlordo

+0

Когда вы сомневаетесь в тестировании! :) +1 – Pragmateek

0

Да, они бы разделили переменную. Правила о статических переменных класса не изменяются в зависимости от использования Generics. Статическая переменная класса используется всеми экземплярами.

+1

Это не должно восприниматься как должное. В C++ 'A ' и 'A ' будут разные классы с различными статическими элементами данных. –

+0

@NicolaMusatti: Это вопрос под тегом 'java' .... – jlordo

+0

Действительно. Однако Java Generics были вдохновлены шаблонами C++, и я думаю, что важно отметить различия. –

0

Все они имеют свои статические атрибуты, потому что во время выполнения A<Integer> и A<String> не являются отдельными классами.

0

Вам просто нужно подумать, что дженерики предназначены для целей компиляции. Во время выполнения нет никакой разницы между A<Integer> и A<String>: все они являются экземплярами A. Таким образом, статические члены являются общими для любых экземпляров, которые вы можете создать, без какого-либо отношения к типу, который вы используете.

3

Хороший вопрос, но anwser есть: нет, вы не можете по очень простой причине: когда компилируетесь нет такого понятия, как < Integer> или А < String>, только потому, что для обратной совместимости причины Java использует generics type-erasure.

На других языках, как C# все будет работать так, как вы ожидаете, потому что C# был создан с самого начала с generics.

+0

Спасибо, что упомянул C#. Оригинал моей мысли исходил из примера C#. – Quirin

+0

Я в аналогичной ситуации: трудно вернуться 10 лет назад при использовании Java, но я уверен, что он заполнит пробел. :) – Pragmateek

2

Нет литерала класса (A<Integer>.class или Class экземпляра), которые представляют собой любой параметризованный тип (например, A<Integer>). Всегда будет только одно для необработанной версии A (т. Е. A.class), и это тот, с которым принадлежат все статические члены.

Вот почему вы не будете делать что-то вроде A<Integer>.member, это всегда должна быть необработанная версия A.member (и это единственная (и единственная), которая используется всеми экземплярами).

Здесь вы можете прочитать статью по этой теме - Is there one instances of a static field per instantiation of a generic type?.

Смежные вопросы