18

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 instance the following example:

Class1 obj = new Class1();

Class1 foo()
{
    return new Class1();
}

Is as easy to read as the more Pythonesque way of writing it:

Class1 obj = Class1();

Class1 foo()
{
    return Class1();
}

EDIT: Cowan hit the nail on the head with the clarification of the question: Why did they choose this syntax?

Community
  • 1
  • 1
dalle
  • 18,057
  • 5
  • 57
  • 81

9 Answers9

24
  1. It's a self documenting feature.
  2. It's a way to make it possible to name a method "Class1" in some other class
Paco
  • 8,335
  • 3
  • 30
  • 41
  • 1
    To the second point: you could do that anyway, but had to qualify it with this.Class1(). the same thing happens now when types and member names collide. – Øyvind Skaar Jan 11 '09 at 22:20
  • 4
    On the other hand, without the new operator, it'd be possible to create a new() function elsewhere. ;) I think the answer is simply "it looks more familiar to the programmers Java/C# are aimed at. – jalf Jan 24 '09 at 16:21
  • 2
    2. That makes it possible yes, but why on earth would you want to go against good naming conventions? You know, classes should be nouns and methods verbs... – Anttu Nov 26 '13 at 09:51
9
Class1 obj = Class1();

In C# and Java, you need the "new" keyword because without it, it treats "Class1()" as a call to a method whose name is "Class1".

Michael
  • 34,873
  • 17
  • 75
  • 109
  • True, but what if that wasn't the case? Why does the `new` operator exist in the first place? – dalle Jan 11 '09 at 20:31
  • 1
    But that *is* the case. You're asking, "What if it wasn't the case that an engine moves a car? Why does an 'engine' exist in the first place?" – Michael Jan 11 '09 at 20:38
  • What if a horse is moving the car and the engine just controls the radio and air conditioning? Or what if some other types of car can move without engine? – Paco Jan 11 '09 at 20:58
  • I'd answer your question, but I have a train that's moved by a ox with an engine that controls the whistle and interior lighting to catch. – Michael Jan 11 '09 at 21:17
  • 12
    It's not the same as asking that at all. The question is "why did they choose this syntax?". It's more like "why did they settle on the _internal combustion_ engine to move cars?", which is a perfectly sensible question and has perfectly sensible answers. – Cowan Jan 11 '09 at 22:09
9

The usefulness is of documentation - it's easier to distinguish object creations from method invocations than in Python.

The reason is historic, and comes straight from the C++ syntax. In C++, "Class1()" is an expression creating a Class1 instance on the stack. For instance: vector a = vector(); In this case, a vector is created and copied to the vector a (an optimizer can remove the redundant copy in some cases).

Instead, "new Class1()" creates a Class1 instance on the heap, like in Java and C#, and returns a pointer to it, with a different access syntax, unlike Java and C++. Actually, the meaning of new can be redefined to use any special-purpose allocator, which still must refer to some kind of heap, so that the obtained object can be returned by reference.

Moreover, in Java/C#/C++, Class1() by itself could refer to any method/function, and it would be confusing. Java coding convention actually would avoid that, since they require class names to start with a upper case letter and method names to start with a lower case one, and probably that's the way Python avoids confusion in this case. A reader expects "Class1()" to create an object, "class1()" to be a function invocation, and "x.class1()" to be a method invocation (where 'x' can be 'self').

Finally, since in Python they chose to make classes be objects, and callable objects in particular, the syntax without 'new' would be allowed, and it would be inconsistent to allow having also another syntax.

Blaisorblade
  • 6,438
  • 1
  • 43
  • 76
  • 2
    It's not just that; there isn't a semantic difference between functions and constructors in Python, at least not from outside the class. Just as you would do `def inc(a):return a + 1; map(inc,somelist)` to increment all the items in `somelist`, you could do `map(int,somelist)` to convert all the items in `somelist` to `int`s. – Imagist Sep 19 '09 at 07:06
5

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.

joshperry
  • 41,167
  • 16
  • 88
  • 103
2

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...

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
2

The reason Java chose it was because the syntax was familiar to C++ developers. The reason C# chose it was because it was familiar to Java developers.

The reason the new operator is used in C++ is probably because with manual memory management it is very important to make it clear when memory is allocated. While the pythonesque syntax could work, it makes is less obvious that memory is allocated.

JacquesB
  • 41,662
  • 13
  • 71
  • 86
1

The new operator allocates the memory for the object(s), which is it's purpose; as you say it also self documents which instance(s) (i.e. a new one) you're working with

Rowland Shaw
  • 37,700
  • 14
  • 97
  • 166
0

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. ..."

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
-1

In addition to remarks above AFAIK they were planning to remove new keyword for Java 7 in early drafts. But later they cancelled it.

systemsfault
  • 15,207
  • 12
  • 59
  • 66