Почему C# и Java беспокоятся “новым” оператором?

17
задан Community 23 May 2017 в 11:53
поделиться

8 ответов

  1. Это сам документирование функции.
  2. Это - способ позволить назвать метод "Class1" в некотором другом классе
24
ответ дан 30 November 2019 в 10:39
поделиться

Полноценность имеет документацию - легче отличить создания объекта от вызовов метода, чем в Python.

причина является исторической, и прибывает прямо из синтаксиса C++. В C++, "Class1 ()" является выражением, создающим экземпляр Class1 на стеке . Например: векторизуйте = вектор (); В этом случае вектор создается и копируется в вектор (оптимизатор может удалить избыточную копию в некоторых случаях).

Вместо этого "новый Class1 ()" создает экземпляр Class1 на "куче" , как в Java и C#, и возвращается указатель к нему, с другим синтаксисом доступа, в отличие от Java и C++. На самом деле значение новых может быть переопределено для использования любого средства выделения специального назначения, которое все еще должно относиться к некоторой "куче", так, чтобы полученный объект мог быть возвращен ссылкой.

, Кроме того, в Java/C#/C ++, Class1 () отдельно мог обратиться к любому методу/функции, и это будет сбивать с толку. Конвенция кодирования Java на самом деле избежала бы, чтобы, так как они требуют, чтобы имена классов начали с прописной буквы и имен методов запускаться с нижнего регистра один, и вероятно это было способом, которым Python избегает беспорядка в этом случае. Читатель ожидает, "что Class1 ()" создаст объект, "class1 ()", чтобы быть вызовом функции, и "x.class1 ()", чтобы быть вызовом метода (где 'x' может быть 'сам').

Наконец, с тех пор в Python они приняли решение заставить классы быть объектами и вызываемыми объектами, в частности, синтаксис без 'нового' будет позволен, и это было бы непоследовательно, чтобы позволить иметь также другой синтаксис.

9
ответ дан 30 November 2019 в 10:39
поделиться
Class1 obj = Class1();

В C# и Java, Вам нужно "новое" ключевое слово, потому что без него, он рассматривает "Class1 ()" как вызов к методу, имя которого является "Class1".

9
ответ дан 30 November 2019 в 10:39
поделиться

Новый оператор в C# отображается непосредственно на инструкцию IL, названную newobj, который на самом деле выделяет место для переменных нового объекта и затем выполняет конструктора (названный .ctor в IL). При казни конструктора - во многом как C++ - ссылка на инициализированный объект передается в как невидимый первый параметр (как thiscall).

подобная thiscall конвенция позволяет времени выполнения загружаться и JIT весь код в памяти для определенного класса только в один раз и снова использовать его для каждого экземпляра класса.

Java может иметь подобный код операции на своем промежуточном языке, хотя я не достаточно знаком для высказывания.

5
ответ дан 30 November 2019 в 10:39
поделиться

Новый оператор выделяет память для объекта (объектов), который является, это - цель; поскольку Вы говорите это также сам документы , который экземпляр (экземпляры) (т.е. новый) Вы работаете с

1
ответ дан 30 November 2019 в 10:39
поделиться

C++ предлагает программистам выбор выделения объектов на "куче" или на стеке.

Стековое выделение более эффективно : выделение является более дешевым, затраты на освобождение являются действительно нулем, и язык оказывает помощь в разграничении объектных жизненных циклов, снижая риск упущения освободить объект.
, С другой стороны, в C++, необходимо быть очень осторожными при публикации или совместном использовании ссылок на стековые объекты, потому что стековые объекты автоматически освобождены, когда стековый фрейм раскручен, ведя к висячим указателям.

С new оператор , все объекты выделяются на "куче" в Java или C#.

Class1 obj = Class1 ();

На самом деле, компилятор попытался бы найти метод названным Class1().

, Например, следующее общая ошибка Java:

public class MyClass
{
  //Oops, this has a return type, so its a method not a constructor!
  //Because no constructor is defined, Java will add a default one.
  //init() will not get called if you do new MyClass();
  public void MyClass()
  {
     init();
  }
  public void init()
  {
     ...
  }
} 
<час>

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

, Например, в Java, оптимизации Горячей точки как escape-анализ использование складывает выделение.

Этот анализ, выполненный компилятором во время выполнения, может прийти к заключению, например, что на объект на "куче" ссылаются только локально в методе, и никакая ссылка не может сбежать из этого объема. Если так, Горячая точка может применить оптимизацию во время выполнения. Это может выделить объект на стеке или в регистрах вместо на "куче".

Такая оптимизация, хотя не всегда , рассмотрела решающий ...

2
ответ дан 30 November 2019 в 10:39
поделиться

В дополнение к комментариям выше AFAIK они планировали удалить новое ключевое слово для Java 7 в ранних проектах. Но позже они отменили его.

-1
ответ дан 30 November 2019 в 10:39
поделиться

Причина Java выбрал его, состояла в том, потому что синтаксис был знаком разработчикам C++. Причина C# выбрал его, состояла в том, потому что это было знакомо Java-разработчикам.

причина new, оператор используется в C++, состоит, вероятно в том, потому что с ручным управлением памятью очень важно прояснить, когда память выделяется. В то время как pythonesque синтаксис мог работать, он делает, менее очевидно, что память выделяется.

2
ответ дан 30 November 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: