4

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

Why does java have the new keyword? To create an object of type A, I have to type A a = new A().

Java doesn't have stack allocation, so why couldn't that just be simplified to A a = A()?

Community
  • 1
  • 1
CromTheDestroyer
  • 3,616
  • 3
  • 20
  • 26
  • A very similar question: http://stackoverflow.com/questions/433591/why-do-c-and-java-bother-with-the-new-operator – makes Jan 16 '11 at 16:27
  • Just to nitpick: Java does have stack allocation, but only for primitive types :) – Uri Jan 16 '11 at 16:32
  • @Uri, and references to objects. – Peter Lawrey Jan 16 '11 at 16:40
  • @Peter: Aren't the references considered primitive types? (except that you can't manipulate their values directly as you can with C pointers?). – Uri Jan 16 '11 at 16:48
  • boolean.class.isPrimtive() is true, I don't think you will find something which says a reference is a primitive. Perhaps you mean java data type which would describe both primitives and references. – Peter Lawrey Jan 16 '11 at 16:53
  • @Peter: I'm trying to recall the JVM spec but don't have time to look it up. I vaguely remember reading somewhere that most of the code handles references in a similar way to the primitive types, but you don't have direct reference to them from the language. But it's been 10 years since I bothered to take a look so I'm probably wrong. – Uri Jan 16 '11 at 18:27

6 Answers6

3

Because C++ did it so, I presume. Java was supposed to look superficially like C++, but with a greatly simplified and streamlined language.

In any case, you got a problem there:

class Foo {
   private static void A() {
     System.out.println("method");
   }

   public static void main(String[] args) {
     A();
   }
}

class A {
  public A() {
    System.out.println("ctor");
  }
}

What should happen here? ctor or method?

Joey
  • 344,408
  • 85
  • 689
  • 683
  • Your A should be static. The way it is, even "new A()" is an error, because java requires x.new A(), where x is of type Foo. – CromTheDestroyer Jan 16 '11 at 16:28
  • You're right, there's an ambiguity there, but it's just a name collision, and it could be resolved like they always are in java: calling the method would be just A(), and calling the constructor would be A.A() – CromTheDestroyer Jan 16 '11 at 16:39
  • So instead of `new A()`, you say `A.A()`? Doesn't save much typing, and seems less readable to me. If i see `new`, i know i'm calling a constructor...no need to disambiguate at all. – cHao Jan 16 '11 at 16:42
  • @cHao: the disambiguation is only needed in a case like the above. How often have you had to deal with classes whose names are exactly the same as static methods in other classes? Especially in java where the convention is for class names to be capitalized, while the first letters of method names are not capitals. I've never come across a case where disambiguation would have been needed if there was no new. – CromTheDestroyer Jan 16 '11 at 17:01
  • @Crom: I have only dealt with ambiguities like that when people do stuff like `public Color Color()` (common in .net, less so in Java). That happens in Java, but it's kinda rare. *Which is why i'd never think to look for it as the cause of some odd problem i was having.* The language allows for classes and methods to have the same names, and it'd be crippled if it couldn't, since *just about anything* could be a class name. Conventions are only that, and Java can't change the identifier rules now without breaking tons of code. They're not going to do it to save someone a couple of keystrokes. – cHao Jan 16 '11 at 17:14
  • I don't think this was done so much "to look like C++" as "because it makes sense", for the reason you give among others. – ColinD Jan 16 '11 at 17:23
  • @ColinD: As far as I'm concerned they pretty much deliberataly copied much of the syntax, downright to the most stupid mistakes C did. I guess there wasn't too much thought involved ... – Joey Jan 16 '11 at 19:24
  • @Joey: C never made that "mistake". There's no `new` in C. And in C++, it does a heap allocation, which is also the case for every object created in Java, so copying the syntax for it made a lot of sense. Add in the most common answer here ("Because doing otherwise would create ambiguity"), and Java's use of `new` seems rather well thought out to me. – cHao Jan 16 '11 at 23:03
  • @cHao: that was aimed generally at syntax (which you may agree closely follows that of C/C++). The C comment wasn't aimed at the `new` keyword. – Joey Jan 16 '11 at 23:56
  • @Joey: I agree the syntax looks quite C++'ish. Minus the pointer stuff, of course. :) C would be going back a bit too far, though. So much of Java's syntax is related to classes and objects, that most of C's syntax wouldn't apply at all. (No `struct`, no arrow operator, `public/private/protected`, and as we've mentioned, `new`.) It seems Java only took from C what had already gotten carried over into C++, so it seems less convoluted to say it took from C++ instead. – cHao Jan 17 '11 at 00:12
2

One obvious drawback to your syntax suggestion is found here:

class A {}

class B extends A {
    public A A() { return new B() }

    public A foo() { return A(); } //ERK            
}

What should the above code in the method foo do? Does it invoke the method named A(), or the constructor of A.

Of course you can now have something like what you want using static imports:

public class A {
    public static A A() { return new A(); }
}

This can be brought into scope by import static my.stuff.A.*

oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • I feel like the real thing demonstrated here is just how crappy your names are. Not to mention the fact that method names generally begin with a lowercase while class names generally begin with an uppercase. – ArtOfWarfare Apr 05 '14 at 13:03
1

That you know you are calling a constructor and not a method.

Sibbo
  • 3,796
  • 2
  • 23
  • 41
  • Well, methods and constructors can't have the same name, at least if they're in the same class. If they're in different classes there are ways of resolving the ambiguity. – CromTheDestroyer Jan 16 '11 at 16:32
  • Thing is, if Java just handles things transparently, *you might not even know there's an ambiguity*. It might be enough to spit out a warning when the compiler has to decide, but too many people ignore warnings. – cHao Jan 16 '11 at 16:38
  • +1 @CromTheDestroyer: It's legal to have a method called `Foo()` in a class which returns an object of type `Foo`. If `Foo` has its own no-arg constructor, `Foo foo = Foo()` is ambiguous. Waving your hand and saying "there are ways of resolving this ambiguity" doesn't help much... `new` is a way of resolving the ambiguity, and it also makes it explicit that you're creating a new object! Method calls that return values certainly don't have to create new objects. – ColinD Jan 16 '11 at 17:20
0

It is arbitrary. Python constructors work more or less like Java constructors, and are just A(), no new required.

david van brink
  • 3,604
  • 1
  • 22
  • 17
0

In Java, classes, methods, and variables have different namespaces, which means in any scope you could have one of each with the same name. It'd be ambiguous to say A a = A();, because there could be a method named A(). Sure, Java could look for a method and use a class constructor if it couldn't find a method...but then, it wouldn't be obvious (from looking just at the code) what it does, and the Java people are big on "purity". Plus, if you happened to add a public A A() to your class, that line of code takes on a whole different meaning.

cHao
  • 84,970
  • 20
  • 145
  • 172
0

It is arbitrary but one could think of many reasons.

One reason would have to do with the mixing of automatic (stack based) and heap-allocation objects and references for them. You know how in C++ you have to be careful about not taking a pointer to an automatic variable? That's one less headache to worry about.

A second reason is likely that Java is generally designed to have low-cost object allocation and low-cost GC for recent objects (thanks to the use of generational garbage collectors). There is therefore no significant benefit to supporting both types of object allocations.

Uri
  • 88,451
  • 51
  • 221
  • 321