it-swarm.com.de

Wie funktioniert System.out.print ()?

Ich habe lange mit Java gearbeitet und habe mich gefragt, wie die Funktion System.out.print() funktioniert.

Hier ist mein Zweifel:

Da es sich um eine Funktion handelt, gibt es irgendwo im Paket io eine Deklaration. Aber wie haben Java-Entwickler das gemacht, da diese Funktion eine beliebige Anzahl von Argumenten und Argumenttypen aufnehmen kann, unabhängig von ihrer Anordnung? z.B:

System.out.print("Hello World");
System.out.print("My name is" + foo);
System.out.print("Sum of " + a + "and " + b + "is " + c);
System.out.print("Total USD is " + usd);

Unabhängig von dem Datentyp der Variablen a, b, c, usd, foo oder wie sie übergeben werden, gibt System.out.print() niemals einen Fehler aus.

Für mich habe ich noch nie an einem Projekt gearbeitet, bei dem die Anforderung so war. Vorausgesetzt, wenn ich eine solche Anforderung bekomme, weiß ich wirklich nicht, wie ich sie lösen soll.

Kann mir jemand erklären, wie es gemacht wird?

14
ikis

System.out ist nur eine Instanz von PrintStream. Sie können dessen JavaDoc überprüfen. Seine Variabilität basiert auf Methodenüberladung (mehrere Methoden mit demselben Namen, aber unterschiedlichen Parametern).

Dieser Druckstrom sendet seine Ausgabe an die sogenannte Standardausgabe .


In Ihrer Frage erwähnen Sie eine Technik namens variadische Funktionen (oder varargs). Leider wird dies nicht von PrintStream#print unterstützt, daher müssen Sie dies mit etwas anderem verwechseln. Es ist jedoch sehr einfach, diese in Java zu implementieren. Überprüfe einfach die Dokumentation.


Wenn Sie wissen möchten, wie Java Nicht-String-Variablen "foo" + 1 + true + myObj verketten kann, liegt dies hauptsächlich in der Verantwortung eines Java-Compilers. 

Wenn an der Verkettung keine Variable beteiligt ist, verkettet der Compiler die Zeichenfolge einfach. Wenn eine Variable involviert ist, wird die Verkettung in StringBuilder#append chain übersetzt. Der resultierende Bytecode enthält keine Verkettungsanweisung. der +-Operator (wenn von String-Verkettung gesprochen wird) wird während der Kompilierung aufgelöst.

Alle Typen in Java können in String (int über Methoden in Integer-Klasse, boolean über Methoden in Boolean-Klasse, Objekte über ihren eigenen #toString, ...) umgewandelt werden. Sie können den Quellcode von StringBuilder bei Interesse überprüfen.


UPDATE: Ich war selbst neugierig und überprüfte (mit javap ), woraus sich mein Beispiel System.out.println("foo" + 1 + true + myObj) zusammensetzt. Das Ergebnis:

System.out.println(new StringBuilder("foo1true").append(myObj).toString());
18
Pavel Horal

Obwohl es so aussieht, als würde System.put.print...() eine variable Anzahl von Argumenten annehmen, ist dies nicht der Fall. Wenn Sie genau hinschauen, wird der String einfach verkettet und Sie können dasselbe mit jedem String tun. Das einzige, was passiert, ist, dass die Objekte, die Sie übergeben, implizit von Java in einen String konvertiert werden, der die toString()-Methode aufruft.

Wenn Sie dies versuchen, wird es fehlschlagen:

    int i = 0;
    String s = i;
    System.out.println(s);

Grund ist, weil hier die implizite Konvertierung nicht erfolgt.

Wenn Sie es jedoch ändern

    int i = 0;
    String s = ""+i;
    System.out.println(s);

es funktioniert und das passiert auch, wenn System.put.print...() verwendet wird.

Wenn Sie eine variable Anzahl von Argumenten in Java implementieren möchten, um etwas wie C printf nachzuahmen, können Sie es wie folgt deklarieren:

public void t(String s, String ... args)
{
    String val = args[1];
}

Was hier passiert ist, dass ein Array von Strings mit der Länge der bereitgestellten Argumente übergeben wird. Hier kann Java die Typüberprüfung für Sie durchführen.

Wenn Sie wirklich eine printf wollen, müssen Sie es so machen:

public void t(String s, Object ... args)
{
    String val = args[1].toString();
}

Dann müssten Sie die Argumente entsprechend interpretieren oder interpretieren.

3
Devolus

Es ist ein sehr sensibler Punkt zu verstehen, wie System.out.print ..__ arbeitet. Wenn das erste Element String ist, arbeitet der Plus (+) - Operator als String-Concate-Operator. Wenn das erste Element eine Ganzzahl ist, arbeitet der Operator Plus (+) als mathematischer Operator.

public static void main(String args[]) {
        System.out.println("String" + 8 + 8); //String88
        System.out.println(8 + 8+ "String"); //16String
    }
1
Samet öztoprak

Offensichtlich wurde der Compiler auf verwirrende Weise erstellt, obwohl die Compiler-Entwickler der Meinung waren, dass sie etwas mehr Intelligenz hinzufügten. Die wahre Intelligenz, die sie wirklich hinzufügen sollten, besteht darin, das gesamte Argument und den Operator + konsistent zu betrachten. Beispielsweise sollte System.out.println(1+2+"hello"+3+4);3hello7 anstelle von 3hello34 ausgeben.

0
Shoujie He

Bei den von Ihnen erwähnten Szenarien handelt es sich nicht um eine Überlastung. Sie verketten lediglich verschiedene Variablen mit einem String.

System.out.print("Hello World");

System.out.print("My name is" + foo);

System.out.print("Sum of " + a + "and " + b + "is " + c); 

System.out.print("Total USD is " + usd);

in all diesen Fällen rufen Sie nur print (String s) auf. Wenn etwas mit einem String verkettet wird, wird es durch Aufruf von toString () dieses Objekts in einen String konvertiert, und die Primitiven werden direkt verkettet Wenn Sie verschiedene Signaturen kennen möchten, ist ja print () für verschiedene Argumente überladen.

0
Saurabh Mishra

Es dreht sich alles um Method Overloading .

Für jeden Datentyp gibt es individuelle Methoden in der println () -Methode

Wenn Sie ein Objekt übergeben:

Druckt ein Objekt und beendet dann die Zeile. Diese Methode ruft zuerst String.valueOf (x) auf, um den String-Wert des gedruckten Objekts abzurufen, und verhält sich dann so, als würde es print (String) und dann println () aufrufen.

Wenn Sie den Primitiv-Typ übergeben:

entsprechende Methodenaufrufe des primitiven Typs

wenn Sie String übergeben: 

korrespondierende Aufrufe der println (String x) -Methode

0
Suresh Atta

Ich denke, Sie sind mit der printf(String format, Object... args) -Methode verwechselt. Das erste Argument ist der Formatstring, der obligatorisch ist. Sie können jedoch eine beliebige Anzahl von Objects übergeben.

Es gibt keine solche Überladung für die Methoden print() und println().

0
Bhesh Gurung

@ikis, erstens, als @Devolus sagte, dass dies keine Mehrfacherweiterungen sind, die an print() übergeben werden. Tatsächlich erhalten all diese übergebenen Argumente die Verknüpfung von , Um einen einzelnen String zu bilden. print() weist also nicht mehrere Argumente auf (a. K. A. Var-args). Nun bleibt das zu diskutierende Konzept, wie print() jeden Typ des übergebenen Arguments druckt. 

Um dies zu erklären - toString() ist das Geheimnis:

System ist eine Klasse mit einem statischen Feld out vom Typ PrintStream. Sie rufen also die println(Object x)-Methode einer PrintStream auf.

Es ist wie folgt implementiert:

 public void println(Object x) {
   String s = String.valueOf(x);
   synchronized (this) {
       print(s);
       newLine();
   }
}

Wie wir sehen, wird die String.valueOf (Object) -Methode aufgerufen. Dies ist wie folgt implementiert:

 public static String valueOf(Object obj) {
   return (obj == null) ? "null" : obj.toString();
}

Und hier sehen Sie, dass toString() aufgerufen wird. 

Was auch immer von der toString()-Methode dieser Klasse zurückgegeben wird, das gleiche wird gedruckt.

Und wie wir wissen, befindet sich die toString() in der Object-Klasse und erbt somit eine Standardimplementierung von Object.

beispiel: Denken Sie daran, wenn wir eine Klasse haben, deren toString() wir überschreiben und dann diese ref-Variable an print übergeben. Was sehen Sie gedruckt? - Wir kommen von der toString() zurück.

0
mohd shoaib

Sie können alles in einen String konvertieren, solange Sie wählen, was gedruckt werden soll. Die Anforderung war ziemlich einfach, da Objet.toString() eine Standard-Dumb-Zeichenfolge zurückgeben kann: package.classname + @ + object number.

Wenn Ihre Druckmethode eine XML- oder JSON-Serialisierung zurückgeben soll, ist das grundlegende Ergebnis von toString () nicht akzeptabel. Obwohl die Methode erfolgreich ist.

Hier ist ein einfaches Beispiel, um zu zeigen, dass Java dumm sein kann

public class MockTest{

String field1;

String field2;

public MockTest(String field1,String field2){
this.field1=field1;
this.field2=field2;
}

}

System.out.println(new MockTest("a","b");

druckt etwas [email protected]! Obwohl Sie nur zwei String-Mitglieder haben und dies zum Drucken implementiert werden kann

[email protected]{"field1":"a","field2":"b"}

(oder so wie es im Debbuger erscheint)

0
mahery rafara