26 votes

Comment fonctionne System.out.print() ?

Je travaille avec Java depuis un certain temps, et je me demandais comment la fonction System.out.print() œuvre.

Voici mes doutes :

Comme il s'agit d'une fonction, elle doit être déclarée quelque part dans le fichier io l'emballage. Mais comment les développeurs de Java ont-ils fait, puisque cette fonction peut prendre n'importe quel nombre d'arguments et n'importe quel type d'argument, quelle que soit la façon dont ils sont disposés ? par exemple :

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

Quel que soit le type de données des variables a, b, c, usd, foo ou la manière dont ils sont adoptés, System.out.print() n'émet jamais d'erreur.

Pour ma part, je n'ai jamais travaillé sur un projet où l'exigence était telle. Pourvu que, si je reçois une exigence de ce type, je ne sache vraiment pas comment la résoudre.

Quelqu'un peut-il m'expliquer comment cela se passe ?

28voto

Pavel Horal Points 5801

System.out est juste une instance de PrintStream . Vous pouvez vérifier son JavaDoc . Sa variabilité est basée sur surcharge des méthodes (plusieurs méthodes portant le même nom, mais avec des paramètres différents).

Ce flux d'impression envoie sa sortie à ce que l'on appelle le sortie standard .


Dans votre question, vous mentionnez une technique appelée fonctions variadiques (ou varargs ). Malheureusement, cela n'est pas pris en charge par PrintStream#print Vous devez donc le confondre avec quelque chose d'autre. Cependant, il est très facile de les mettre en œuvre en Java. Il suffit de vérifier la documentation.


Et si vous êtes curieux de savoir comment Java sait concaténer des variables qui ne sont pas des chaînes de caractères "foo" + 1 + true + myObj C'est principalement la responsabilité d'un compilateur Java.

Lorsqu'il n'y a pas de variable impliquée dans la concaténation, le compilateur concatène simplement la chaîne. Lorsqu'une variable est impliquée, la concaténation est traduite en StringBuilder#append chaîne. Il n'y a pas d'instruction de concaténation dans le code d'octets résultant, c'est-à-dire que l'instruction + (lorsqu'il s'agit de la concaténation de chaînes de caractères) est résolu lors de la compilation.

Tous les types de Java peuvent être convertis en chaînes de caractères ( int par le biais de méthodes dans Integer classe, boolean par le biais de méthodes dans Boolean les objets via leur propre #toString , ...). Vous pouvez consulter le code source de StringBuilder si vous êtes intéressé.


UPDATE : Par curiosité, j'ai vérifié (à l'aide de javap ) ce que mon exemple System.out.println("foo" + 1 + true + myObj) se compile en . Le résultat :

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

3voto

Devolus Points 10549

Même s'il semble que System.put.print...() prend un nombre variable d'arguments, il ne le fait pas. Si vous regardez bien, la chaîne est simplement concaténée et vous pouvez faire la même chose avec n'importe quelle chaîne. La seule chose qui se produit est que les objets que vous passez sont implicitement convertis en chaîne de caractères par java en appelant la fonction toString() méthode.

Si vous essayez de le faire, vous échouerez :

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

La raison en est qu'ici la conversion implicite n'est pas effectuée.

Toutefois, si vous le remplacez par

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

Cela fonctionne et voici ce qui se passe lorsque l'on utilise System.put.print...() également.

Si vous voulez implémenter un nombre variable d'arguments en java pour mimimc, quelque chose comme C printf vous pouvez le déclarer comme suit :

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

Ce qui se passe ici, c'est qu'un tableau de chaînes de caractères est transmis, avec la longueur des arguments fournis. Ici, Java peut faire la vérification du type pour vous.

Si vous voulez vraiment un printf, vous devez le faire comme ceci :

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

Il faudrait alors interpréter les arguments en conséquence.

3voto

Samet öztoprak Points 552

Il est très important de comprendre comment System.out.print fonctionne. Si le premier élément est une chaîne de caractères, l'opérateur plus(+) fonctionne comme un opérateur de concaténation de chaînes de caractères. Si le premier élément est un entier, l'opérateur plus(+) fonctionne comme un opérateur mathématique.

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

1voto

Shoujie He Points 11

De toute évidence, le compilateur a été conçu de manière confuse, bien que les développeurs du compilateur aient pensé qu'ils avaient ajouté de l'intelligence. La véritable intelligence qu'ils devraient ajouter est de regarder l'argument entier et d'interpréter l'opérateur + de manière cohérente. Par exemple, System.out.println(1+2+"hello"+3+4); devrait produire 3hello7 au lieu de 3hello34

0voto

Il s'agit de Surcharge des méthodes .

Il existe des méthodes individuelles pour chaque type de données dans méthode println()

Si vous passez l'objet :

Imprime un objet et termine la ligne. Cette méthode appelle d'abord String.valueOf(x) pour obtenir la valeur de la chaîne de l'objet imprimé, puis se comporte comme si elle invoquait print(String) puis println().

Si vous passez le type Primitive :

les appels de méthodes des types primitifs correspondants

si vous passez String :

Les appels à la méthode println(String x) correspondants

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X