147

The new keyword in languages like Java, Javascript, and C# creates a new instance of a class.

This syntax seems to have been inherited from C++, where new is used specifically to allocate a new instance of a class on the heap, and return a pointer to the new instance. In C++, this is not the only way to construct an object. You can also construct an object on the stack, without using new - and in fact, this way of constructing objects is much more common in C++.

So, coming from a C++ background, the new keyword in languages like Java, Javascript, and C# seemed natural and obvious to me. Then I started to learn Python, which doesn't have the new keyword. In Python, an instance is constructed simply by calling the constructor, like:

f = Foo()

At first, this seemed a bit off to me, until it occurred to me that there's no reason for Python to have new, because everything is an object so there's no need to disambiguate between various constructor syntaxes.

But then I thought - what's really the point of new in Java? Why should we say Object o = new Object();? Why not just Object o = Object();? In C++ there's definitely a need for new, since we need to distinguish between allocating on the heap and allocating on the stack, but in Java all objects are constructed on the heap, so why even have the new keyword? The same question could be asked for Javascript. In C#, which I'm much less familiar with, I think new may have some purpose in terms of distinguishing between object types and value types, but I'm not sure.

Regardless, it seems to me that many languages which came after C++ simply "inherited" the new keyword - without really needing it. It's almost like a vestigial keyword. We don't seem to need it for any reason, and yet it's there.

Question: Am I correct about this? Or is there some compelling reason that new needs to be in C++-inspired memory-managed languages like Java, Javascript and C# but not Python?

12
  • 13
    The question is rather why any language has the new keyword. Of course I want to create a new variable, stupid compiler! A good language would in my opinion have a syntax like f = heap Foo(), f = auto Foo().
    – user29079
    Oct 31, 2011 at 15:25
  • 8
    A very important point to consider is how familiar a language looks to new programmers. Java was explicitly designed to look familiar to C/C++ programmers.
    – user1249
    Oct 31, 2011 at 18:59
  • 4
    @Lundin: It's really a result of compiler technology. A modern compiler wouldn't even need hints; it would figure out where to put the object based on your actual use of that variable. I.e. when f doesn't escape the function, allocate stack space.
    – MSalters
    Nov 1, 2011 at 9:52
  • 3
    @Lundin: It can, and in fact modern JVM's do. It's merely a matter of proving that the GC can collect object f when the enclosing function returns.
    – MSalters
    Nov 1, 2011 at 15:13
  • 1
    It's not constructive to ask why a language is designed the way it is, particularly if that design asks us to type four extra characters for no obvious benefit? What am I missing?
    – Tyler
    Jan 30, 2013 at 3:40

15 Answers 15

100

Your observations are correct. C++ is a complicated beast, and the new keyword was used to distinguish between something that needed delete later and something that would be automatically reclaimed. In Java and C#, they dropped the delete keyword because the garbage collector would take care of it for you.

The problem then is why did they keep the new keyword? Without talking to the people who wrote the language it's kind of difficult to answer. My best guesses are listed below:

  • It was semantically correct. If you were familiar with C++, you knew that the new keyword creates an object on the heap. So, why change expected behavior?
  • It calls attention to the fact that you are instantiating an object rather than calling a method. With Microsoft code style recommendations, method names start with capital letters so there can be confusion.

Ruby is somewhere in between Python and Java/C# in it's use of new. Basically you instantiate an object like this:

f = Foo.new()

It's not a keyword, it's a static method for the class. What that means is that if you want a singleton, you can override the default implementation of new() to return the same instance every time. It's not necessarily recommended, but it's possible.

11
  • 6
    The Ruby syntax looks nice and consistent! The new keyword in C# is also used as a generic type constraint for a type with a default constructor. Feb 14, 2011 at 16:28
  • 3
    Yes. We won't talk about generics though. Both Java and C#'s version of generics are very obtuse. Not saying C++ is much easier to understand though. Generics really are only useful for statically typed languages. Dynamically typed languages like Python, Ruby, and Smalltalk just don't need them. Feb 14, 2011 at 17:30
  • 2
    Delphi has a similar syntax to Ruby, except that constructors are usually (but only bhy convention) called Create (`f := TFoo.Create(param1, param2...)'
    – Gerry
    Feb 14, 2011 at 20:16
  • In Objective-C, the alloc method (roughly the same thing as Ruby's new) is also just a class method.
    – mipadi
    Feb 15, 2011 at 18:02
  • 5
    From language design perspective, keywords are bad for many reasons, mainly you cannot change them. On the other hand reusing the concept of method is easier, but needs some attention while parsing and analysing. Smalltalk and its kin use messages, C++ and itskin on the other hand keywords Feb 16, 2011 at 11:10
89

In short, you are right. Keyword new is superfluous in languages like Java and C#. Here are some insights from Bruce Eckel who was a member of C++ Standard Comitee in 1990s and later published books on Java: http://www.artima.com/weblogs/viewpost.jsp?thread=260578

there needed to be some way to distinguish heap objects from stack objects. To solve this problem, the new keyword was appropriated from Smalltalk. To create a stack object, you simply declare it, as in Cat x; or, with arguments, Cat x("mittens");. To create a heap object, you use new, as in new Cat; or new Cat("mittens");. Given the constraints, this is an elegant and consistent solution.

Enter Java, after deciding that everything C++ is badly done and overly complex. The irony here is that Java could and did make the decision to throw away stack allocation (pointedly ignoring the debacle of primitives, which I've addressed elsewhere). And since all objects are allocated on the heap, there's no need to distinguish between stack and heap allocation. They could easily have said Cat x = Cat() or Cat x = Cat("mittens"). Or even better, incorporated type inference to eliminate the repetition (but that -- and other features like closures -- would have taken "too long" so we are stuck with the mediocre version of Java instead; type inference has been discussed but I will lay odds it won't happen. And shouldn't, given the problems in adding new features to Java).

2
  • 2
    Stack vs Heap... insightful, never would have thought of it.
    – WernerCD
    Feb 15, 2011 at 0:25
  • 1
    "type inference has been discussed but I will lay odds it won't happen.", :) Well, the development of Java still goes forward. Interesting that this is the only flagship for Java 10 though. The var keyword is nowhere close as good as auto in C++, but I hope it will improve.
    – patrik
    Jun 20, 2018 at 22:26
15

There's two reasons I can think of:

  • new distinguishes between an object and a primitive
  • The new syntax is a bit more readable (IMO)

The first is trivial. I don't think it's any harder to tell the two apart either way. The second is an example of the OP's point, which is that new is sort of redundant.

There could be namespace conflicts, though; consider:

public class Foo {
   Foo() {
      // Constructor
   }
}

public class Bar {
   public static void main(String[] args) {
      Foo f = Foo();
   }

   public Foo Foo() {
      return Foo();
   }
}

You could, without too much stretching of the imagination, easily end up with an infinitely recursive call. The compiler would have to enforce a "Function name same as object" error. This really wouldn't hurt, but it is far simpler to use new, which states, Go to the object of the same name as this method and use the method that matches this signature. Java is a very simple language to parse, and I suspect this assists in that area.

2
  • 1
    How is this any different to any other infinite recursion?
    – DeadMG
    Oct 28, 2011 at 12:37
  • That's a fairly good illustration of a bad thing that could happen, although the developer that does that would have some serious mental issues.
    – Tjaart
    Oct 30, 2012 at 12:32
11

In JavaScript you need it because the constructor looks like a normal function, so how should JS know that you want to create a new object if it wasn't for the new keyword?

Invoking a JavaScript function with the new operator results in different behavior than invoking a function without the new operator.

For example:

Date()       //Returns a string

new Date()   //Returns a Date object
function foo() {};

foo()        //Returns `undefined`

new foo()    //Returns an empty object
10

Java, for one, still has the dichotomy of C++: not quite everything is an object. Java has built-in types (e.g., char and int) that don't have to be allocated dynamically.

That doesn't mean that new is really necessary in Java though -- the set of types that don't need to be allocated dynamically is fixed and known. When you define an object, the compiler could know (and, in fact, does know) whether it's a simple value that char or an object that has to be allocated dynamically.

I'll refrain (yet again) from opining on what this means about the quality of Java's design (or lack thereof, as the case may be).

1
  • More to the point, the primitive types don't need any constructor call at all – they either are written as a literal, come from an operator, or from some primitive-returning function. You actually also create strings (which are on the heap) without a new, so this isn't really the reason. Sep 23, 2019 at 22:26
4

Interestingly, VB does need it - the distinction between

Dim f As Foo

which declares a variable without assigning it, the equivalent of Foo f; in C#, and

Dim f As New Foo()

which declares the variable and assigns a new instance of the class, the equivalent of var f = new Foo(); in C#, is a substantive distinction. In pre-.NET VB, you could even use Dim f As Foo or Dim f As New Foo - because there was no overloading on constructors.

3
  • 4
    VB doesn't need the shorthand version, it's just an abbreviation. You can also write the longer version with type and constructor Dim f As Foo = New Foo() . With Option Infer On, which is the nearest thing to C#'s var, you can write Dim f = New Foo() and the compiler infers the type of f.
    – MarkJ
    Oct 29, 2012 at 7:56
  • 2
    ...and Dim f As Foo() declares an array of Foos. Oh joy! :-)
    – Heinzi
    Oct 30, 2012 at 12:56
  • @MarkJ: In vb.net, the shorthand is equivalent. In vb6, it wasn't. In vb6, Dim Foo As New Bar would effectively make Foo a property that would construct a Bar if it was read while (i.e. Nothing). This behavior wasn't limited to happening once; setting Foo to Nothing and then reading it would create another new Bar.
    – supercat
    Mar 13, 2014 at 4:03
4

I like a lot of answers and would just like to add this:
It makes the reading of code easier
Not that this situation would happen often, but consider you wanted a method in the name of a verb that shared the same name as a noun. C# and other language naturally have the word object reserved. But if it were not then would Foo = object() be the result of the object method call or would it be instantiating a new object. Hopefully said language without the new keyword has protections against this situation, but by have the requirement of the new keyword before the calling of a constructor you allow the existence of a method with the same name as an object.

2
  • 4
    Arguably, having to know this is a bad sign.
    – DeadMG
    Oct 28, 2011 at 12:11
  • 1
    @DeadMG: “Arguably” means “I'll argue that until the bar closes”… Oct 30, 2012 at 14:39
3

There's a lot of vestigial stuff in many programming languages. Sometimes it's there by design (C++ was designed to be as compatible as possible with C), sometimes, it's just there. For a more egregious example, consider how far the broken C switch statement propagated.

I don't know Javascript and C# well enough to say, but I see no reason for new in Java except that C++ had it.

2
  • I think JavaScript was designed to "look just like Java" as much possible, even when it's doing something particularly un-Java-like. x = new Y() in JavaScript doesn't instantiate the Y class, because JavaScript doesn't have classes. But it looks like Java so it carries the new keyword forward from Java, which of course carried it forward from C++.
    – Tyler
    Oct 31, 2011 at 16:05
  • +1 for the broken switch (in the hope you repair it :D).
    – maaartinus
    Oct 17, 2013 at 1:38
3

In C# it allows types visible in contexts where they might otherwise be obscured by a member. The allows you to have a property with same name as a its type. Consider the following,

class Address { 
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

class Person {
    public string Name { get; set; }
    public Address Address { get; set; }

    public void ChangeStreet(string newStreet) {
        Address = new Address { 
            Street = newStreet, 
            City = Address.City,
            State = Address.State,
            Zip = Address.Zip
        };
    }
}

Note the use of new allows it to be clear that Address is the Address type not the Address member. This allows a member to have the same name as its type. Without this you would need to prefix the name of the type to avoid the name collision, such as CAddress. This was very intentional as Anders never liked hungarian notation or anything similar and wanted to C# to be usable without it. The fact it was also familiar was a double bonus.

4
  • w00t, and Address could then derive from an interface called Address.. only, no it can't. So its not much of a benefit, being able to reuse the same name and decrease from the general readability of your code. So by keeping the I for interfaces, but removing the C from classes, they just created a nasty smell for no practical benefit.
    – gbjbaanb
    Oct 31, 2012 at 12:12
  • I wonder that they don't use "New" instead of "new". Somebody could tell them there are also lowercase letters, which sort of solve this problem.
    – maaartinus
    Oct 17, 2013 at 1:36
  • All reserved words in C derived languages, such as C#, are lower case. The grammar requires a reserved word here to avoid ambiguity thus the use of "new" instead of "New".
    – chuckj
    Oct 17, 2013 at 22:16
  • @gbjbaanb There is no smell. It is always utterly clear whether you're referring to a type or a property/member or a function. The real smell is when you name a namespace the same as a class. MyClass.MyClass
    – Stephen
    May 20, 2015 at 23:50
0

Interestingly, with the advent of perfect forwarding, non-placement new isn't required at all in C++ either. So, arguably, it's no longer needed in any of the mentioned languages.

2
  • 4
    What do you forward to? Ultimately, std::shared_ptr<int> foo(); will have to call new int somehow.
    – MSalters
    Nov 1, 2011 at 9:56
  • It will certainly be required. The way std::string and std::vector, for example, was designed, is by using std::allocator<T> which is all based on new and delete. Nov 19, 2023 at 5:07
0

I'm not sure whether Java designers had this in mind but when you think of objects as recursive records, then you could imagine that Foo(123) doesn't returns an object but a function whose fixpoint is the object being created (ie. function that would return the object if it's given as argument the object being constructed). And the purpose of new is to "tie the knot" and return that fixpoint. In other words new would make the "object-to-be" aware of its self.

This kind of approach could help formalizing inheritance for example: you could extend an object-function with another object-function and finally provide them with common self by using new:

cp = new (Colored("Blue") & Line(0, 0, 100, 100))

Here & combines two object-functions.

In this case new could be defined as:

def new(objectFunction) {
    actualObject = objectFunction(actualObject)
    return actualObject
}
-2

To allow 'nil'.

Along with heap based allocation, Java embraced the use of nil objects. Not just as an artifact, but as a feature. When objects can have a nil state, then you have to separate declaration from initialisation. Hence the new keyword.

In C++ a line like

Person me;

Would instantly call the default constructor.

3
  • 4
    Um, what's wrong with Person me = Nil or having Person me be Nil by default and using Person me = Person() for non-Nil? My point is that it doesn't seem that Nil was a factor in this decision...
    – Andres F.
    Oct 30, 2012 at 13:15
  • You have a point. Person me = Person(); would work equally well. Oct 30, 2012 at 23:51
  • @AndresF. Or even simpler with Person me being nil and Person me() invoking the default constructor. So you'd always need parentheses in order to invoke anything, and thus get rid of one C++ irregularity.
    – maaartinus
    Aug 3, 2014 at 19:49
-2

The reason why Python does not need it is because of its type system. Fundamentally, when you see foo = bar() in Python, it doesn't matter what whether bar() is a method that is being invoked, a class that is being instantiated, or a functor object; in Python, there is no fundamental difference between a functor and function (because methods are objects); and you could even argue that a class being instantiated is a special case of a functor. Thus, there is no reason to create an artifical difference in what is happening (especially since memory management is so extremely hidden in Python).

In a language with a different typing system, or in which methods and classes are not objects, there is the possibility of a stronger conceptual difference between creating an object and calling a function or functor. Thus, even if the compiler/interpreter does not need the new keyword, it is understandable that it might be maintained in languages that haven't broken all the boundaries that Python has.

-4

Actually in Java there is a difference when using Strings:

String myString = "myString";

is different from

String myString = new String("myString");

Supposing the string "myString" has never been used before, the first statement creates a single String object in the String pool (a special area of the heap) while the second statement creates two objects, one in the normal heap area for objects and other in String pool. It is pretty obvious that the second statement is useless in this particular scenario, but is allowable by the language.

This means that new assures that the object is created in that special area of the heap, allocated for normal object instantiation, but there may be other ways of instantiating objects without it; the above one is an example, and there is room left for extensibility.

9
  • 3
    But this wasn't the question. The question was "why not String myString = String("myString");?" (note the absence of the new keyword)
    – Andres F.
    Jan 29, 2013 at 21:42
  • @AndresF. Kind of obvious imho... it is legal to have a method named String that returns a String in a String class and there has to be a difference between calling it and calling the constructor. Something like class MyClass { public MyClass() {} public MyClass MyClass() {return null;} public void doSomething { MyClass myClass = MyClass();}} //which is it, constructor or method?
    – Random42
    Jan 29, 2013 at 22:03
  • 3
    But it's not obvious. First, having a regular method named String goes against Java style conventions, so you can just assume any method starting with uppercase is a constructor. And second, if we aren't constrained by Java, then Scala has "case classes" where the constructor looks exactly like I said. So where is the problem?
    – Andres F.
    Jan 29, 2013 at 23:11
  • 2
    Sorry, I don't follow your argument. You are effectively arguing syntax, not semantics, and anyway the question was about new for managed languages. I have shown that new is not at all needed (e.g. Scala doesn't need it for case classes) and also that there is no ambiguity (since you absolutely cannot have a method named MyClass in class MyClass anyway). There is no ambiguity for String s = String("hello"); it cannot be anything else but a constructor. And finally, I disagree: code conventions are there to enhance and clarify the syntax, which is what you're arguing about!
    – Andres F.
    Jan 30, 2013 at 16:17
  • 1
    So that's your argument? "Java designers needed the new keyword because otherwise Java's syntax would have been different"? I'm sure you can see the weakness of that argument ;) And yes, you keep discussing syntax, not semantics. Also, backwards compatibility with what? If you are designing a new language, such as Java, you are already incompatible with C and C++!
    – Andres F.
    Jan 30, 2013 at 17:51
-8

In C# new is important to distinguish between objects created on the stack vs. the heap. Frequently we create objects on the stack for better performance. See, when a object on the stack goes out of scope, it disappears immediately when the stack unravels, just like a primitive. There is no need for the garbage collector to keep track of it, and there is no extra overhead of the memory manager to allocate the necessary space on the heap.

1
  • 5
    unfortunately you're confusing C# with C++.
    – gbjbaanb
    Oct 31, 2012 at 12:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.