Что делает ключевое слово `new`? - программирование
Подтвердить что ты не робот

Что делает ключевое слово `new`?

Я следую учебному курсу Java в Интернете, пытаясь выучить язык, и он подпрыгивает между двумя семантиками для использования массивов.

long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;

и

long results[] = {1, 2, 3};

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

  • Существуют ли определенные "массивы" конкретные методы, которые не будут работать в массиве, если это не "объект массива"?
  • Есть ли что-нибудь, что я не могу сделать с "объектом массива", который я могу сделать с обычным массивом?
  • Нужно ли виртуальной машине Java очищать объекты, инициализированные оператором new, что обычно не нужно делать?

Я прихожу с C, поэтому моя терминология Java, возможно, неверна здесь, поэтому, пожалуйста, попросите пояснить, если что-то непонятное.

4b9b3361

Ответ 1

В Java все массивы и объекты выделяются в куче, поэтому в определенном смысле все массивы являются "объектами массива". Единственными вещами, которые когда-либо были выделены в стеке на Java, являются ссылки на объекты и примитивы. Все остальное - это объект, который определен и распределен в куче, включая массивы, независимо от того, какой синтаксис вы используете для его объявления. (Ваши два примера эквивалентны в конечном результате, см. JLS §10.3 и связанные с ним разделы, чтобы узнать больше о том, как каждый из них фактически назначен и назначен.)

Это противоречит C/С++, где у вас есть явный контроль над распределением стека и кучи.

Обратите внимание, что Java очень быстро, когда речь идет о краткосрочном распределении/освобождении объекта. Он очень эффективен благодаря сборщику мусора на основе генератора. Поэтому, чтобы ответить на ваши вопросы:

Существуют ли определенные "массивы" конкретные методы, которые не будут работать в массиве, если это не "объект массива"? Есть ли что-то, что я не могу сделать с "объектом массива", который я могу сделать с нормальным массивом?

Нет такой вещи, как массив, который не является объектом, поэтому нет. Однако существуют методы, которые не будут работать на примитивных массивах. Метод, принимающий Object[], не примет long[], не преобразовывая его сначала в long[]. Это связано с некоторыми деталями реализации автобоксинга в Java 5 и выше.

Нужно ли виртуальной машине Java очищать объекты, инициализированные оператором new, которые обычно не нужно делать?

Все, что выделяется с помощью new, должно быть в конечном итоге собрано в мусор, поэтому с точки зрения чего-либо, что обычно не делалось? Нет. Однако обратите внимание, что в C/С++ выделение массива с использованием malloc/new означает, что вы также должны free/delete [] его, что вам не нужно делать на Java, поскольку оно будет восстанавливать массив для вас.

Обратите внимание, что если ваш long[] объявлен в методе и вы никогда не храните его в ссылке где-то вне вашего метода, он будет автоматически помечен для сбора мусора в конце вызова метода. Сборщик мусора будет ждать, чтобы вернуть свое пространство, пока оно ему не понадобится, но вам не нужно выполнять какую-либо рекультивацию самостоятельно через delete [] (или delete и деструкторы для объектов).

Изменить: некоторые ссылки, как и обещалось:

Ответ 2

Ключевое слово new в Java создает новый объект. В этом случае он создает массив... который является объектом.

Эти две формы эквивалентны. Второй - просто удобная стенограмма для первой. Это синтаксический сахар.

Существуют ли определенные "массивы" конкретные методы, которые не будут работать в массиве, если это не "объект массива"?

Все массивы - это объекты. Период.

Есть ли что-нибудь, что я не могу сделать с "объектом массива", который я могу сделать с обычным массивом?

См. выше.

Нужно ли виртуальной машине Java очищать объекты, инициализированные новым оператором, что обычно не нужно делать?

Нет. Нет никакой разницы между объектами, созданными по-разному в отношении JVM.

Ответ 3

Оба идентичны с точки зрения поведения созданного массива. Все массивы являются технически объектами в java; это всего лишь два разных способа их инициализации. Также возможно совместить их так:

long[] results = new long[]{1,2,3};

Ответ 4

Оба они одинаковы. Второй вариант делает неявное создание объекта массива, это просто для удобства пользователя.

Ответ 5

От JLS#Chapter 10. Arrays

На языке программирования Java массивы являются объектами (§4.3.1), динамически создаются и могут быть назначены переменным типа Object (§ 4.3.3). Все методы класса Object могут быть вызваны в массиве.

Из 10.3. Array Creation

Массив создается выражением создания массива (§15.10) или инициализатором массива (§10.6)

Из 15.10. Array Creation Expressions

Выражение создания массива создает объект, который представляет собой новый массив, чьи элементы имеют тип, указанный PrimitiveType или ClassOrInterfaceType.

Из 10.6. Array Initializers

Инициализатор массива может быть указан в объявлении (§8.3, §9.3, §14.4) или как часть выражения создания массива (§15.10) для создания массива и предоставления некоторых начальных значений.

Оба инициализируют массив, второй - второй, с некоторыми значениями.

Ответ 6

Два способа создания, которые вы показали, эквивалентны. Оба являются "объектами массива" - помните, что все в Java (за исключением основных числовых типов, таких как int, double и т.д.) Являются объектами. Во-вторых, это просто сокращение для первого, в значительной степени в том, что C имеет аналогичную сокращенную последовательность для массивов с целыми массивами.

Ответ 7

Следующие два фрагмента кода равны в уровне компиляции. Я пишу класс Demo вроде:

public class NewArray {
    public static void main(String[] args) {
        long results[] = new long[3];
    }
}

и

public class NewArray {
    public static void main(String[] args) {
        long results[] = {0,0,0};
    }
}

вывод "javap -c NewArray" точно такой же:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   newarray long
   3:   astore_1
   4:   return

}

длинные результаты [] = новый long [] {1,2,3}; и длинные результаты [] = {1,2,3}; точно такие же.

Итак, хотя иногда вы не используете новое ключевое слово, но компилятор будет считать их равными.

Ответ 8

Ключевое слово 'new' создает массив. Теперь, в зависимости от того, какой тип данных массив для значений внутри него, меняется. Если вы объявите массив как целое число и используете ключевое слово 'new', то он будет содержать значения 0, если вы не измените значения внутри. С помощью String оно будет содержать значение "null". В каждом отдельном пространстве.

Ответ 9

В обоих случаях вы создаете объект.

В первой версии:

long results[] = new long[3];
results[0] = 1;
results[1] = 2;
results[2] = 3;

вы говорите в первой строке, что размер массива равен 3. Затем вы помещаете значения в массив.

Во второй версии:

long results[] = {1, 2, 3};

Вы создаете тот же массив и инициализируете его в той же строке. Java вычисляет, что вы дали 3 аргумента и делает new long[3] без вашей помощи:)