Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Статическое поле в generics/template

#java #c_sharp #c++ #generics


Есть Java generics класс типа:

public class MyClass {
   static long myField=System.currentTimeMillis();

   //blah-blah
}


Создаются два объекта:

MyClass var1=new MyClass();
MyClass var2=new MyClass();


вопрос: одинаковы ли var1.myField и var2.myField?

Update

А если это будет шаблон в С++/C# - тогда будут они одинаковы или нет?
    


Ответы

Ответ 1



У Java с type erasure MyClass и MyClass — это по сути в рантайме один и тот же класс. У C# нет type erasure, поэтому MyClass и MyClass — разные классы. Отсюда следует и различие в статических полях: если класс один и тот же, статическое поле общее. У C++ template — это вообще текстовая подстановка по сути, каждый шаблон класса инстанциируется в отдельный класс, соответственно и статические переменные там разделены.

Ответ 2



Ответ: Да, они одинаковые для Java Ваш пример не самый хороший для демонстрации этого. Известно, что StringBuilder не ссылается в один pool и каждый раз создаёт новый объект. Будем использовать его для подтверждения утверждения: public class Clazz { static StringBuilder myField= new StringBuilder("Test text"); public static void main (String args[]) throws InterruptedException { Clazz var1=new Clazz(); Clazz var2=new Clazz(); // Одинаковые ли ссылки на объект? System.out.println(var1.myField == var2.myField); // Одинаковы ли содержания объектов? System.out.println(var1.myField.toString().equals(var2.myField.toString())); } } Output: true true В C++, на сколько я понял, нет прямого аналога generic class. Там есть шаблоны и работают они как-то по-другому. Я набросал немного кода: template class Test { public: static int count; }; template int Test ::count; int main() { Test a; Test b; Test c; a.count = 2; b.count = 1; c.count = 1; // Одинаковы ли ссылки? cout << (&a.count == &b.count) << endl; // Одинаковы ли содержания? cout << (a.count == b.count)<< endl; // Одинаковы ли ссылки? cout << (&a.count == &c.count) << endl; // Одинаковы ли содержания? cout << (a.count == c.count) << endl; return 0; } Статическая переменная внутри шаблона оказывается одинаковой для объектов, созданных одинаковым типом (int) и разная для разных типов. Вывод этой программы следующий: Output: 1 1 0 1 В C# провести исследование нет возможности (ОС не поддерживает), но я нашёл похожий вопрос на англоязычном StackOverflow: Are static members of a generic class tied to the specific instance?. Дела там, похоже, не особо отличаются от C++. Статическая переменная одинакова для всех экземпляров одинакового типа. Foo и Foo - два разных типа. Это можно показать в следующем примере: // Результатом будет "False" Console.WriteLine(typeof(Foo) == typeof(Foo)); Это можно найти в 1.6.5 параграфе спецификации языка C# (for C# 3): ....

Ответ 3



C#: нет, они разные class Generic { static object obj = new object(); public object GetObject() { return obj; } } static void Main() { var g1 = new Generic(); var g2 = new Generic(); Console.WriteLine( (g1.GetObject() == g2.GetObject() ? string.Empty : "Not ") + "Same"); } Output: Not Same

Ответ 4



Для C++ разные, т.к. разные типы аргумента для шаблона порождают разные классы, никак не связанные друг с другом. #include template struct MyClass { static long myField; }; int main() { auto var1 = MyClass(); auto var2 = MyClass(); std::cout << std::boolalpha << (&var1.myField == &var2.myField) << std::endl; } Вывод: false

Комментариев нет:

Отправить комментарий