public static void Main()
{
Test t1 = new Test();
}
когда будет, t1 (ссылочная переменная) получит память, во время компиляции или время выполнения.
Я думаю, что это должно быть время выполнения. Но когда я поместил точку останова в Основной метод и Помещенный Часы для t1, это было пустым. Таким образом, это означает, что t1 был в памяти.
Исправьте меня, Если я неправ.
Править: Я слышал, что Статические членские Переменные присвоены во время компиляции.
Последовательность - это массив символов. Поскольку это массив, он не может быть примитивом!: -)
-121--1706247- «Primitive» в Java обычно принимают за «value type». Однако C # имеет ключевое слово последовательностей
, которое действует точно так же, как и Последовательность Java, оно просто выделяется редактором по-разному. Они являются псевдонимами для классов System. Последовательность
или java.lang. Последовательность
. Последовательность не является типом значения ни на одном языке, поэтому таким образом она не является примитивом.
Если под «примитивом» подразумевается встроенный в язык, то последовательность является примитивом. Просто используется заглавная буква. Строковые литералы (в кавычках) автоматически преобразуются в System.String
и + используется для конкатенации. Таким образом, они (и Массивы) являются такими же примитивными, как ints, longs и т. д.
Последовательность не является оберткой. Последовательность - это ссылочный тип , а примитивные типы - типы значений . Это означает, что если у вас есть:
int x = 5;
int y = x;
Память x и y оба содержат «5». Но с:
String x = "a";
String y = x;
Память x и y оба содержат указатель на символ «a» (и длину, смещение, указатель ClassInfo и монитор). Последовательности ведут себя как примитив, потому что они незыблемы, поэтому обычно это не проблема, однако если вы, скажем, использовали отражение, чтобы изменить содержимое последовательности ( не делать этого! ), как x, так и y увидят изменение. На самом деле, если у вас есть:
char[] x = "a".toCharArray();
char[] y = x;
x[0] = 'b';
System.out.println(y[0] == 'b'); // prints "true"
Так что не просто использовать char [] (если это не поведение вы хотите, или вы действительно пытаетесь уменьшить использование памяти).
Каждый объект
является ссылочным типом - это означает все записываемые классы, каждый класс в структуре и даже массивы. Единственными вещами, которые являются ценностными типами, являются простые числовые типы (int, long, short, byte, float, double, char, bool и т. д.)
Для этого есть несколько причин, но в основном это сводится к психологии и деталям реализации:
В основном, данные о производительности и реализации,а также сложность наличия 2 различных типов последовательностей. Другие типы значений имеют фиксированный объем памяти. Int - это всегда 32 бит, long - это всегда 64 бит, bool - это всегда 1 бит и т. д. 2 Помимо прочего, это означает, что они могут храниться в стеке, так что все параметры функции живут в одном месте. Кроме того, создание гигантских копий последовательностей по всему месту может убить производительность.
См. также: Почему в C # последовательность является ссылочным типом, который ведет себя как тип значения? . Относится к .NET, но это так же применимо в Java.
1 - В C/C + + и других самокомпилируемых языках это верно, потому что они помещаются в сегмент кода процесса, который ОС обычно останавливает редактирование. В Java это на самом деле обычно не соответствует действительности, так как JVM загружает файлы классов в кучу, чтобы там можно было редактировать последовательность. Однако нет причин, по которым Java-программа не может быть скомпилирована (есть инструменты, которые делают это), и некоторые архитектуры (особенно некоторые версии ARM) выполняют непосредственно байт-код Java.
2 - На практике некоторые из этих типов имеют различный размер на уровне машины. E.x. буллы хранятся в стеке как WORD-size (32 бита на x86, 64 бита на x64). В классах/массивах они могут обрабатываться по-разному. Это все детали реализации, которые остались до JVM - спецификация говорит, что булы являются либо истинными, либо ложными, и машина может выяснить, как это сделать.
-121--1706242-Ссылка t1 назначается в стеке метода Main - присвоенное ей значение (т.е. часть «new Test ()») назначается в куче во время выполнения - поэтому переменная t1 существует до выполнения этой строки и имеет значение null.
Память выделяется только во время выполнения (во время компиляции Ваше приложение не работает).
Во время выполнения ваша T1
переменная будет иметь значение только (то есть не NULL
после того, как присвоение произошло, так что это зависит от того, где вы помещаете точку останова. Если вы поместите свою точку останова на закрывающуюся скобу вашего метода Main
и проверьте окно часов, когда он ударит, вы увидите, что я имею в виду.
I.e. Если вы поместите свою точку останова на строку назначения TEST1 T1 = NEW TEST1 ();
, то эта линия еще не выполнена, поэтому назначение не произошло.
Test t1;
Эта часть выделяет достаточно места только для ссылки (вероятно, 4 байта во многих случаях, но я думаю, что это действительно зависит от реализации .NET Framework), и определяется при компиляционном времени и выделено (я думаю), когда называется Main Отказ
t1 = new Test();
Эта строка, когда она запускается, выделит достаточно места для хранения данных для тестового объекта, а затем назначить существующую ссылочную переменную T1 для обозначения этой вновь выделенной памяти. Так что теперь у вас есть место для T1 плюс пространство для нового теста () как выделено.
Редактировать: Чтобы ответить на ваше редактирование, статические переменные элемента разные, и ваша локальная переменная ведет себя по-разному, чем они. Тем не менее, я не верю, что статические переменные участника выделяются при компиляционном времени. Я думаю, что они выделяются, когда тип, содержащий их, загружен (который, кажется, когда вызывается любая функция, которая относится к типу).
class Test2
{
public static Test f1 = new Test();
}
Этот код создаст новый экземпляр теста, как только функция, которая содержит любую ссылку на Type Test2.
в начале «основного», память кучи для экземпляра не была выделена Тем не менее (и не будет до нового теста ()
). Он останется выделенным до тех пор, пока не собирается мусор.
Локальная переменная, Test T1
(на основе стека), что будет ссылаться на память кучи (и существует в течение всего времени, что «главное» выполняется).
Оба из них являются заданиями времени выполнения, но различаются с точки зрения того, где находится память, и для того, как долго.
Статические поля выделяются при нагрузках типа (и инициализированы некоторое время между первым использованием типа).
С помощью «Compile Time» я не уверен, что вы относитесь к JIT Compile - но в зависимости от того, что память выделяется отдельно от компиляции.
Вы должны быть в состоянии понять это одно самостоятельно. Просто подумайте об этом:
Выделение компиляции памяти - просто не имеет никакого смысла ...
Нет, это означает, что T1 еще не назначен. После того, как вы позвоните в новый тест T1 ()
T1, будет выделено память для хранения размера объекта
, и присваивается адрес памяти.
Да память выделяется только во время выполнения.
Ссылка t1 назначается в стеке метода Main - присвоенное ей значение (т.е. часть «new Test ()») назначается в куче во время выполнения - поэтому переменная t1 существует до выполнения этой строки и имеет значение null.
-121--4648512-В окнах необходимо получить доступ к идентификатору необработанного устройства в виде файла. Он должен работать, если вы передаете файл «\\.\c: », вы используете UNC-имя устройства\.\c: (\. означает эту машину).
Для Vista и более поздних версий я не думаю, что это будет работать правильно, так как существуют механизмы для предотвращения необработанного доступа к диску для чего-либо, кроме драйверов устройств (не цитируйте меня на этом)
-121--2313435-запустить приложение в режиме отладки, F5 в основном является сочетанием клавиш в Visual Studio. Установите точку останова в этом заявлении. Используйте F10 для перехода к следующей инструкции. Как только отладчик выполнит следующую инструкцию, вы увидите создаваемый объект.