views:

1343

answers:

10

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?

+1  A: 

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
Calling new for structs in C# doesn't allocate memory though.
dalle
It does, just on the stack, rather than the heap
Rowland Shaw
Not really, it is already allocated when the function is entered.
dalle
+16  A: 
  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
I really like your second point.
dalle
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
That's true, but you might have readability issues then.
Paco
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
+11  A: 
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 Angstadt
True, but what if that wasn't the case? Why does the `new` operator exist in the first place?
dalle
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 Angstadt
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
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 Angstadt
My own bullshit is confusing me now...
Paco
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
Thank you Cowan for understanding my question.
dalle
A: 

Have you considered using static methods?

class Class1 { public static Class1 Instance() { return new Class1(); } }

Class1 obj = Class1.Instance();

Class1 foo() { return Class1.Instance(); }

static methods are not applicable for every situation
gnomixa
+4  A: 

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 it's intermediate language, thought I am not familiar enough to say.

joshperry
+6  A: 

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
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
+1  A: 

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

VonC
A: 

Self-documenting feature, and also probably helps with build performance.

Class1 obj = Class1();

is obvious and easy to understand but what about

Class1 obj = HappyHappyJoyJoy();

when HappyHappyJoyJoy is a subclass of Class1?

Gerald
A: 

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
A: 

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