Warum haben speicherverwaltete Sprachen wie Java, Javascript und C # das Schlüsselwort `new` beibehalten?

139

Das newSchlüsselwort in Sprachen wie Java, Javascript und C # erstellt eine neue Instanz einer Klasse.

Diese Syntax scheint von C ++ geerbt worden zu sein, wo newspeziell eine neue Instanz einer Klasse auf dem Heap zugeordnet und ein Zeiger auf die neue Instanz zurückgegeben wird. In C ++ ist dies nicht die einzige Möglichkeit, ein Objekt zu erstellen. Sie können auch ein Objekt auf dem Stapel erstellen, ohne new- zu verwenden, und tatsächlich ist diese Art der Erstellung von Objekten in C ++ weitaus üblicher.

Aus einem C ++ - Hintergrund stammend, newerschien mir das Schlüsselwort in Sprachen wie Java, Javascript und C # natürlich und offensichtlich. Dann fing ich an, Python zu lernen, das das newSchlüsselwort nicht hat . In Python wird eine Instanz einfach durch Aufrufen des Konstruktors wie folgt erstellt:

f = Foo()

Anfangs schien mir das ein bisschen abwegig zu sein, bis mir klar wurde, dass es für Python keinen Grund gibt new, weil alles ein Objekt ist und man nicht zwischen verschiedenen Konstruktorsyntaxen unterscheiden muss.

Aber dann dachte ich mir - worum geht es eigentlich newin Java? Warum sollten wir sagen Object o = new Object();? Warum nicht einfach Object o = Object();? In C ++ ist dies definitiv erforderlich new, da zwischen Zuweisung auf dem Heap und Zuweisung auf dem Stack unterschieden werden muss, in Java jedoch alle Objekte auf dem Heap erstellt werden. Warum also überhaupt das newSchlüsselwort? Dieselbe Frage könnte für Javascript gestellt werden. In C #, mit dem ich weniger vertraut bin, newkann es meiner Meinung nach sinnvoll sein, zwischen Objekttypen und Werttypen zu unterscheiden, aber ich bin mir nicht sicher.

Unabhängig davon scheint es mir, dass viele Sprachen, die nach C ++ kamen, das newSchlüsselwort einfach "geerbt" haben - ohne es wirklich zu brauchen. Es ist fast wie ein Schlagwort . Wir scheinen es aus keinem Grund zu brauchen, und doch ist es da.

Frage: Habe ich diesbezüglich Recht? Oder gibt es einen zwingenden Grund, newder in C ++ inspirierten speicherverwalteten Sprachen wie Java, Javascript und C # liegen muss, aber nicht in Python?

Channel72
quelle
13
Die Frage ist eher, warum eine Sprache das newSchlüsselwort hat. Natürlich möchte ich einen neuen variablen, blöden Compiler erstellen! Eine gute Sprache wäre meiner Meinung nach einer Syntax wie f = heap Foo(), f = auto Foo().
7
Ein sehr wichtiger Punkt ist, wie vertraut eine Sprache für neue Programmierer aussieht. Java wurde explizit entwickelt, um C / C ++ - Programmierern vertraut zu sein.
1
@Lundin: Es ist wirklich ein Ergebnis der Compilertechnologie. Ein moderner Compiler würde nicht einmal Hinweise brauchen; es würde herausfinden, wo das Objekt zu platzieren ist, basierend auf Ihrer tatsächlichen Verwendung dieser Variablen. Dh, wenn fdie Funktion nicht verlassen wird, wird Stapelspeicher zugewiesen.
MSalters
3
@Lundin: Das kann es, und in der Tat tun es moderne JVMs. Es muss nur bewiesen werden, dass der GC Objekte sammeln kann, fwenn die umschließende Funktion zurückkehrt.
MSalters
1
Es ist nicht konstruktiv zu fragen, warum eine Sprache so gestaltet ist, wie sie ist, insbesondere wenn wir bei diesem Entwurf aufgefordert werden, vier zusätzliche Zeichen einzugeben, ohne dass ein offensichtlicher Nutzen daraus entsteht. Was vermisse ich?
MatrixFrog

Antworten:

94

Ihre Beobachtungen sind richtig. C ++ ist ein kompliziertes Biest, und das newSchlüsselwort wurde verwendet, um zwischen etwas zu unterscheiden, das deletespäter benötigt wurde, und etwas, das automatisch zurückgefordert werden würde. In Java und C # haben sie das deleteSchlüsselwort gelöscht, weil der Garbage Collector es für Sie erledigen würde.

Das Problem ist dann, warum sie das newSchlüsselwort behalten haben ? Ohne mit den Leuten zu sprechen, die die Sprache geschrieben haben, ist es schwierig zu antworten. Meine besten Vermutungen sind unten aufgeführt:

  • Es war semantisch korrekt. Wenn Sie mit C ++ vertraut waren, wussten Sie, dass das newSchlüsselwort ein Objekt auf dem Heap erstellt. Warum also das erwartete Verhalten ändern?
  • Es macht darauf aufmerksam, dass Sie ein Objekt instanziieren, anstatt eine Methode aufzurufen. Bei Empfehlungen für Microsoft-Codestile beginnen Methodennamen mit Großbuchstaben, sodass Verwirrung herrschen kann.

Ruby ist irgendwo zwischen Python und Java / C # in seiner Verwendung new. Grundsätzlich instanziieren Sie ein Objekt wie folgt:

f = Foo.new()

Es ist kein Schlüsselwort, sondern eine statische Methode für die Klasse. Dies bedeutet, dass Sie, wenn Sie einen Singleton wünschen, die Standardimplementierung von überschreiben können, um new()jedes Mal dieselbe Instanz zurückzugeben. Es ist nicht unbedingt zu empfehlen, aber es ist möglich.

Berin Loritsch
quelle
5
Die Ruby-Syntax sieht gut und konsistent aus! Das neue Schlüsselwort in C # wird auch als generische Typeinschränkung für einen Typ mit einem Standardkonstruktor verwendet.
Steven Jeuris
3
Ja. Wir werden jedoch nicht über Generika sprechen. Sowohl die Java- als auch die C # -Version von Generika sind sehr stumpf. Nicht zu sagen, dass C ++ viel einfacher zu verstehen ist. Generika sind wirklich nur für statisch typisierte Sprachen nützlich. Dynamisch getippte Sprachen wie Python, Ruby und Smalltalk brauchen sie einfach nicht.
Berin Loritsch
2
Delphi hat eine ähnliche Syntax wie Ruby, mit der Ausnahme, dass Konstruktoren normalerweise (aber nur nach der Konvention) Create (`f: = TFoo.Create (param1, param2 ...) 'heißen
Gerry
In Objective-C ist die allocMethode (ungefähr die gleiche wie die von Ruby's new) ebenfalls nur eine Klassenmethode.
mipadi
3
Aus Sicht des Sprachdesigns sind Stichwörter aus vielen Gründen schlecht. Sie können sie hauptsächlich nicht ändern. Andererseits ist die Wiederverwendung des Methodenkonzepts einfacher, erfordert jedoch einige Aufmerksamkeit beim Parsen und Analysieren. Smalltalk und seine Verwandten verwenden Nachrichten, C ++ und itskin dagegen Schlüsselwörter
Gabriel Ščerbák
86

Kurz, Sie haben recht. Das Schlüsselwort new ist in Sprachen wie Java und C # überflüssig. Hier einige Einblicke von Bruce Eckel, der 1990 Mitglied des C ++ Standard Comitee war und später Bücher über Java veröffentlichte: http://www.artima.com/weblogs/viewpost.jsp?thread=260578

Es musste eine Möglichkeit geben, Heap-Objekte von Stack-Objekten zu unterscheiden. Um dieses Problem zu lösen, wurde das neue Schlüsselwort von Smalltalk übernommen. Um ein Stapelobjekt zu erstellen, deklarieren Sie es einfach wie in Cat x; oder mit Argumenten Cat x ("Fäustlinge") ;. Um ein Heap-Objekt zu erstellen, verwenden Sie new wie in new Cat. oder neue Katze ("Fäustlinge") ;. Angesichts der Einschränkungen ist dies eine elegante und konsistente Lösung.

Geben Sie Java ein, nachdem Sie festgestellt haben, dass alles in C ++ schlecht gemacht und zu komplex ist. Die Ironie dabei ist, dass Java die Entscheidung treffen konnte und tat, die Stapelzuweisung zu verwerfen (wobei das Debakel der Primitiven, das ich an anderer Stelle angesprochen habe, bewusst ignoriert wurde). Und da alle Objekte auf dem Heap zugeordnet sind, muss nicht zwischen Stapel- und Heapzuordnung unterschieden werden. Sie könnten leicht Cat x = Cat () oder Cat x = Cat ("Fäustlinge") gesagt haben. Oder noch besser: Eingebaute Typinferenz zur Eliminierung der Wiederholung (aber das - und andere Features wie Closures - hätten "zu lange" gedauert, sodass wir stattdessen bei der mittelmäßigen Version von Java bleiben; Typinferenz wurde diskutiert, aber ich werde es tun Dies wird wahrscheinlich nicht passieren und sollte auch nicht passieren, wenn man die Probleme beim Hinzufügen neuer Funktionen zu Java bedenkt.

Nemanja Trifunovic
quelle
2
Stack vs Heap ... aufschlussreich, hätte nie daran gedacht.
WernerCD
1
"Typinferenz wurde diskutiert, aber ich nehme an, dass es nicht passieren wird.", :) Nun, die Entwicklung von Java schreitet immer noch voran. Interessant, dass dies das einzige Flaggschiff für Java 10 ist. Das varSchlüsselwort ist bei weitem nicht so gut wie autoin C ++, aber ich hoffe, es wird sich verbessern.
patrik
15

Ich kann mir zwei Gründe vorstellen:

  • new unterscheidet zwischen einem Objekt und einem Primitiv
  • Die newSyntax ist etwas besser lesbar (IMO)

Der erste ist trivial. Ich glaube nicht, dass es schwieriger ist, die beiden so oder so auseinander zu halten. Die zweite ist ein Beispiel für den Punkt des OP, newder redundant ist.

Es kann jedoch zu Namespace-Konflikten kommen. Erwägen:

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

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

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

Sie könnten, ohne zu viel Vorstellungskraft, leicht zu einem unendlich rekursiven Aufruf kommen. Der Compiler müsste den Fehler "Funktionsname wie Objekt" erzwingen. Das würde wirklich nicht schaden, aber es ist viel einfacher zu benutzen new, was besagt, dass Go to the object of the same name as this method and use the method that matches this signature.Java eine sehr einfach zu analysierende Sprache ist, und ich vermute, dass dies in diesem Bereich hilfreich ist.

Michael K
quelle
1
Wie unterscheidet sich das von einer anderen unendlichen Rekursion?
DeadMG
Das ist eine ziemlich gute Illustration für eine schlechte Sache, die passieren könnte, obwohl der Entwickler, der das macht, einige ernsthafte mentale Probleme haben würde.
Tjaart
10

Java, für einen, hat immer noch die Dichotomie von C ++: nicht ganz alles ein Objekt ist. Java verfügt über integrierte Typen (z. B. charund int), die nicht dynamisch zugewiesen werden müssen.

Dies bedeutet jedoch nicht, dass newdies in Java wirklich notwendig ist - die Menge der Typen, die nicht dynamisch zugewiesen werden müssen, ist fest und bekannt. Wenn Sie ein Objekt definieren, weiß der Compiler möglicherweise (und tatsächlich), ob es sich um einen einfachen Wert handelt charoder um ein Objekt, das dynamisch zugewiesen werden muss.

Ich werde (noch einmal) davon Abstand nehmen, darüber zu urteilen, was dies für die Qualität von Javas Design bedeutet (oder, je nachdem, dessen Fehlen).

Jerry Sarg
quelle
Darüber hinaus benötigen die primitiven Typen überhaupt keinen Konstruktoraufruf - sie sind entweder als Literal geschrieben, stammen von einem Operator oder von einer primitiven Rückgabefunktion. Sie erstellen tatsächlich auch Strings (die sich auf dem Heap befinden) ohne ein new, das ist also nicht wirklich der Grund.
Paŭlo Ebermann
9

In JavaScript benötigen Sie es, da der Konstruktor wie eine normale Funktion aussieht. Woher sollte JS wissen, dass Sie ein neues Objekt erstellen möchten, wenn das neue Schlüsselwort nicht vorhanden ist?

user281377
quelle
4

Interessanterweise VB tut es brauchen - die Unterscheidung zwischen

Dim f As Foo

deklariert eine Variable, ohne sie zuzuweisen, das Äquivalent von Foo f;in C # und

Dim f As New Foo()

Das Deklarieren der Variablen und Zuweisen einer neuen Instanz der Klasse, die der var f = new Foo();in C # entspricht, ist eine wesentliche Unterscheidung. In pre-.NET VB konnten Sie sogar Dim f As Foooder verwenden, Dim f As New Fooda Konstruktoren nicht überlastet wurden.

Richard Gadsden
quelle
4
VB nicht benötigt die Kurzversion, es ist nur eine Abkürzung. Sie können auch die längere Version mit Typ und Konstruktor Dim f As Foo = New Foo () schreiben. Mit der Option Infer On, die C # am nächsten kommt, können Sie Dim f = New Foo () schreiben, und der Compiler leitet den Typ von f ab.
MarkJ
2
... und Dim f As Foo()deklariert ein Array von Foos. Oh Freude! :-)
Heinzi
@ MarkJ: In vb.net ist die Kurzform gleichbedeutend. In vb6 war es nicht. In vb6 Dim Foo As New Barwürde effektiv Fooeine Eigenschaft erstellt, die a erstellt, Barwenn es während (ie Nothing) gelesen wurde . Dieses Verhalten war nicht auf ein einziges Mal beschränkt. Setzen Sie Fooauf Nothingund lesen Sie es dann, um eine weitere neue zu erstellen Bar.
Superkatze
4

Ich mag viele Antworten und möchte Folgendes hinzufügen:
Es erleichtert das Lesen von Code.
Nicht, dass diese Situation häufig vorkommt, aber Sie möchten eine Methode im Namen eines Verbs, das denselben Namen wie ein Substantiv hat. C # und andere Sprachen haben natürlich das Wort objectreserviert. Wäre dies nicht der Foo = object()Fall, wäre dies das Ergebnis des Objektmethodenaufrufs oder würde ein neues Objekt instanziiert. Es ist zu hoffen, dass die Sprache ohne das newSchlüsselwort Schutz vor dieser Situation bietet. Wenn Sie jedoch das newSchlüsselwort vor dem Aufruf eines Konstruktors benötigen, können Sie die Existenz einer Methode zulassen, die denselben Namen wie ein Objekt hat.

Kavet Kerek
quelle
4
Es ist wohl ein schlechtes Zeichen, das wissen zu müssen.
DeadMG
1
@DeadMG: "Wohl" bedeutet "Ich werde das argumentieren, bis die Bar schließt" ...
Donal Fellows
3

In vielen Programmiersprachen gibt es eine Menge Überbleibsel. Manchmal ist es beabsichtigt da (C ++ wurde entwickelt, um mit C so kompatibel wie möglich zu sein), manchmal ist es einfach da. Betrachten Sie für ein ungeheuerlicheres Beispiel, wie weit sich die gebrochene C- switchAnweisung verbreitet hat.

Ich kenne Javascript und C # nicht gut genug, um es zu sagen, aber ich sehe keinen Grund für newJava, außer dass C ++ es hatte.

David Thornley
quelle
Ich denke, JavaScript wurde so entworfen, dass es so gut wie möglich "wie Java aussieht", auch wenn es etwas tut, das nicht Java-ähnlich ist. x = new Y()in JavaScript nicht instanziiert die YKlasse, weil kein JavaScript haben Klassen. Aber es sieht aus wie Java, also überträgt es das newSchlüsselwort von Java, was es natürlich von C ++ weiterleitet.
MatrixFrog
+1 für den kaputten Schalter (in der Hoffnung, dass Sie ihn reparieren: D).
Maaartinus
3

In C # können Typen in Kontexten angezeigt werden, in denen sie ansonsten von einem Member verdeckt werden könnten. Mit können Sie eine Eigenschaft mit demselben Namen wie den Typ haben. Folgendes berücksichtigen,

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
        };
    }
}

Beachten Sie die Verwendung von new, um zu verdeutlichen, dass Addresses sich bei dem AddressTyp nicht um das AddressMitglied handelt. Auf diese Weise kann ein Mitglied denselben Namen wie sein Typ haben. Ohne dies müssten Sie dem Namen des Typs ein Präfix voranstellen, um die Namenskollision zu vermeiden, z CAddress. Dies war sehr beabsichtigt, da Anders die ungarische Notation oder ähnliches nie mochte und wollte, dass C # ohne sie verwendet werden kann. Die Tatsache, dass es auch bekannt war, war ein doppelter Bonus.

chuckj
quelle
w00t, und Address könnte dann von einer Schnittstelle mit dem Namen Address abgeleitet werden. Nur, nein, kann es nicht. Es ist also kein großer Vorteil, denselben Namen wiederverwenden zu können und die allgemeine Lesbarkeit Ihres Codes zu beeinträchtigen. Indem sie das I für Interfaces beibehalten, aber das C aus den Klassen entfernen, erzeugen sie nur einen unangenehmen Geruch ohne praktischen Nutzen.
gbjbaanb
Ich frage mich, dass sie nicht "Neu" anstelle von "Neu" verwenden. Jemand könnte ihnen sagen, dass es auch Kleinbuchstaben gibt, die dieses Problem lösen.
Maaartinus
Alle reservierten Wörter in C-abgeleiteten Sprachen, wie z. B. C #, werden in Kleinbuchstaben geschrieben. Die Grammatik verlangt hier ein reserviertes Wort, um Mehrdeutigkeiten zu vermeiden, also die Verwendung von "new" anstelle von "New".
Chuckj
@ gbjbaanb Es riecht nicht. Es ist immer völlig klar, ob Sie sich auf einen Typ oder eine Eigenschaft / ein Element oder eine Funktion beziehen. Der eigentliche Geruch ist, wenn Sie einen Namespace wie eine Klasse benennen. MyClass.MyClass
Stephen
0

Interessanterweise ist mit dem Aufkommen der perfekten Weiterleitung das Nicht-Platzieren auch newin C ++ überhaupt nicht erforderlich. Es wird also wohl in keiner der genannten Sprachen mehr benötigt.

DeadMG
quelle
4
Was leiten Sie an ? Werde letztendlich irgendwie std::shared_ptr<int> foo();anrufen müssen new int.
MSalters
0

Ich bin mir nicht sicher, ob Java-Designer dies im Auge hatten, aber wenn Sie sich Objekte als rekursive Datensätze vorstellen, können Sie sich vorstellen, dass Foo(123)dies kein Objekt zurückgibt, sondern eine Funktion, deren Fixpunkt das zu erstellende Objekt ist (dh eine Funktion, die zurückkehren würde) das Objekt, wenn es als Argument angegeben ist). Und der Zweck von newist, "den Knoten zu binden" und diesen Fixpunkt zurückzugeben. Mit anderen Worten, newwürde das "Objekt-zu-sein" dessen bewusst machen self.

Diese Art der Vorgehensweise kann zum Beispiel bei der Formalisierung der Vererbung hilfreich sein: Sie können eine Objektfunktion mit einer anderen Objektfunktion erweitern und diese schließlich selfmithilfe der newfolgenden Methoden gemeinsam bereitstellen :

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

Hier werden &zwei Objektfunktionen kombiniert.

In diesem Fall newkönnte definiert werden als:

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

Null zulassen.

Neben der Heap-basierten Zuweisung hat Java die Verwendung von Null-Objekten übernommen. Nicht nur als Artefakt, sondern als Feature. Wenn Objekte den Status Null haben können, müssen Sie die Deklaration von der Initialisierung trennen. Daher das neue Schlüsselwort.

In C ++ eine Zeile wie

Person me;

Würde sofort den Standardkonstruktor aufrufen.

Kris Van Bael
quelle
4
Ähm, was ist falsch daran Person me = Niloder Person meNil zu haben und Person me = Person()für Nicht-Nil zu verwenden? Mein Punkt ist, dass es nicht so aussieht, als ob Nil ein Faktor bei dieser Entscheidung war ...
Andres F.
Du hast einen Punkt. Person ich = Person (); würde genauso gut funktionieren.
Kris Van Bael
@AndresF. Oder noch einfacher, Person mewenn Sie null sind und Person me()den Standardkonstruktor aufrufen. Sie brauchen also immer Klammern, um irgendetwas aufzurufen und so eine C ++ - Unregelmäßigkeit zu beseitigen.
Maaartinus
-2

Der Grund, warum Python es nicht benötigt, liegt an seinem Typsystem. Grundsätzlich spielt es foo = bar()in Python keine Rolle, ob bar()eine Methode aufgerufen, eine Klasse instanziiert oder ein Funktionsobjekt ist. In Python gibt es keinen grundlegenden Unterschied zwischen einem Funktor und einer Funktion (da Methoden Objekte sind). und man könnte sogar argumentieren, dass eine instanziierte Klasse ein Sonderfall eines Funktors ist. Daher gibt es keinen Grund, einen künstlichen Unterschied im Geschehen zu schaffen (zumal die Speicherverwaltung in Python so extrem verborgen ist).

In einer Sprache mit einem anderen Typensystem oder in der Methoden und Klassen keine Objekte sind, besteht die Möglichkeit eines stärkeren konzeptionellen Unterschieds zwischen dem Erstellen eines Objekts und dem Aufrufen einer Funktion oder eines Funktors. Selbst wenn der Compiler / Interpreter das newSchlüsselwort nicht benötigt , ist es verständlich, dass es in Sprachen verwaltet wird, die nicht alle Grenzen von Python überschreiten.

Kazark
quelle
-4

Tatsächlich gibt es in Java einen Unterschied bei der Verwendung von Strings:

String myString = "myString";

unterscheidet sich von

String myString = new String("myString");

Angenommen, der String "myString"wurde noch nie zuvor verwendet, erstellt die erste Anweisung ein einzelnes String-Objekt im String-Pool (einem speziellen Bereich des Heap-Speichers), während die zweite Anweisung zwei Objekte erstellt, eines im normalen Heap-Bereich für Objekte und eines im String-Pool . Es ist ziemlich offensichtlich, dass die zweite Aussage in diesem speziellen Szenario nutzlos ist, aber von der Sprache zugelassen wird.

Dies bedeutet, dass new sicherstellt, dass das Objekt in diesem speziellen Bereich des Heaps erstellt wird, der für die normale Objektinstanziierung reserviert ist. Es gibt jedoch auch andere Möglichkeiten, Objekte ohne diesen Bereich zu instanziieren. Das obige Beispiel ist ein Beispiel, und es ist noch Raum für Erweiterbarkeit vorhanden.

m3th0dman
quelle
2
Aber das war nicht die Frage. Die Frage war "warum nicht String myString = String("myString");?" (Beachten Sie das Fehlen des newSchlüsselworts)
Andres F.
@AndresF. Eine Methode mit dem Namen String, die einen String in einer String-Klasse zurückgibt, ist zulässig, und es muss ein Unterschied zwischen dem Aufruf und dem Aufruf des Konstruktors bestehen. So etwas wieclass MyClass { public MyClass() {} public MyClass MyClass() {return null;} public void doSomething { MyClass myClass = MyClass();}} //which is it, constructor or method?
m3th0dman
3
Aber es ist nicht offensichtlich. Erstens verstößt eine reguläre Methode mit dem Namen Stringgegen Java-Konventionen, sodass Sie davon ausgehen können, dass jede Methode, die mit Großbuchstaben beginnt, ein Konstruktor ist. Und zweitens, wenn wir nicht durch Java eingeschränkt sind, hat Scala "case classes", bei denen der Konstruktor genau so aussieht, wie ich es gesagt habe. Wo liegt also das Problem?
Andres F.
2
Entschuldigung, ich folge Ihrem Argument nicht. Sie argumentieren effektiv mit der Syntax , nicht mit der Semantik, und die Frage galt sowieso newfür verwaltete Sprachen . Ich habe gezeigt, dass dies überhaupt newnicht erforderlich ist (z. B. benötigt Scala es nicht für Fallklassen) und dass es auch keine Mehrdeutigkeit gibt (da Sie MyClassin der Klasse MyClasssowieso keine Methode haben können). Es gibt keine Mehrdeutigkeit für String s = String("hello"); es kann nichts anderes als ein Konstruktor sein. Und schließlich bin ich anderer Meinung: Code-Konventionen dienen dazu, die Syntax zu verbessern und zu klären, worüber Sie streiten!
Andres F.
1
Also ist das dein Argument? "Java-Designer brauchten das newSchlüsselwort, weil sonst die Syntax von Java anders gewesen wäre"? Ich bin sicher, Sie können die Schwäche dieses Arguments erkennen;) Und ja, Sie diskutieren weiterhin die Syntax, nicht die Semantik. Auch Abwärtskompatibilität mit was? Wenn Sie eine neue Sprache wie Java entwerfen, sind Sie bereits inkompatibel mit C und C ++!
Andres F.
-8

In C # new ist es wichtig, zwischen auf dem Stapel erstellten Objekten und dem Heap zu unterscheiden. Häufig erstellen wir Objekte auf dem Stapel, um die Leistung zu verbessern. Sehen Sie, wenn ein Objekt auf dem Stapel den Gültigkeitsbereich verlässt, verschwindet es sofort, wenn sich der Stapel auflöst, genau wie ein Grundelement. Es ist nicht erforderlich, dass der Garbage Collector den Überblick behält, und es gibt keinen zusätzlichen Aufwand für den Speichermanager, um den erforderlichen Speicherplatz auf dem Heap zuzuweisen.

pds
quelle
5
Leider verwechseln Sie C # mit C ++.
gbjbaanb