Why do C# and Java bother with the “new” operator?

后端 未结 9 1038
隐瞒了意图╮
隐瞒了意图╮ 2020-12-03 13:59

Why does the new operator exist in modern languages such as C# and Java? Is it purely a self documenting code feature, or does it serve any actual purpose?

For insta

相关标签:
9条回答
  • 2020-12-03 14:55

    The new operator in C# maps directly to the IL instruction called newobj which actually allocates the space for the new object's variables and then executes the constructor (called .ctor in IL). When executing the constructor -- much like C++ -- a reference to the initialized object is passed in as an invisible first parameter (like thiscall).

    The thiscall-like convention allows the runtime to load and JIT all of the code in memory for a specific class only one time and reuse it for every instance of the class.

    Java may have a similar opcode in its intermediate language, though I am not familiar enough to say.

    0 讨论(0)
  • 2020-12-03 14:59

    C++ offers programmers a choice of allocating objects on the heap or on the stack.

    Stack-based allocation is more efficient: allocation is cheaper, deallocation costs are truly zero, and the language provides assistance in demarcating object lifecycles, reducing the risk of forgetting to free the object.
    On the other hand, in C++, you need to be very careful when publishing or sharing references to stack-based objects because stack-based objects are automatically freed when the stack frame is unwound, leading to dangling pointers.

    With the new operator, all objects are allocated on the heap in Java or C#.

    Class1 obj = Class1();

    Actually, the compiler would try to find a method called Class1().

    E.g. the following is a common Java bug:

    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()
      {
         ...
      }
    } 
    

    Note: "all objects are allocated on the heap" does not mean stack allocation is not used under the hood occasionally.

    For instance, in Java, Hotspot optimization like escape analysis uses stack allocation.

    This analysis performed by the runtime compiler can conclude for example that an object on the heap is referenced only locally in a method and no reference can escape from this scope. If so, Hotspot can apply runtime optimizations. It can allocate the object on the stack or in registers instead of on the heap.

    Such optimization though is not always considered decisive...

    0 讨论(0)
  • 2020-12-03 15:02

    As others have noted, Java and C# provide the new syntax because C++ did. And C++ needed some way to distinguish between creating an object on the stack, creating an object on the heap, or calling a function or method that returned a pointer to an object.

    C++ used this particular syntax because the early object-oriented language Simula used it. Bjarne Stroustrup was inspired by Simula, and sought to add Simula-like features to C. C had a function for allocating memory, but didn't guarantee that a constructor was also called.

    From "The Design and Evolution of C++," 1994, by Bjarne Stroustrup, page 57:

    Consequently, I introduced an operator to ensure that both allocation and initialization was done:

    monitor* p = new monitor;

    The operator was called new because that was the name of the corresponding Simula operator. The new operator invokes some allocation function to obtain memory and then invokes a constructor to initialize that memory. The combined operation is often called instantiation or simply object creation: it creates an object out of raw memory.

    The notational convenience offered by operator new is significant. ..."

    0 讨论(0)
提交回复
热议问题