2013-06-15 3 views
10

私はかなり長い間Javaを扱ってきましたが、私はどのようにして関数System.out.print()が動作するのだろうかと思っていました。System.out.print()はどのように機能しますか?

はここに私の疑問です:

機能なので、それはどこかIOパッケージで宣言されています。しかし、Java開発者はどのようにしてこの機能を実行しましたか?この機能は、どのように配列されていても、任意の数の引数と引数型を取り入れることができるためです。例えば:

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

どんなに変数a, b, c, usd, fooまたはそれらがどのように渡されるのデータ型が何であるか、System.out.print()はエラーをスローすることはありません。

私にとっては、要件がこのようなプロジェクトでは一度も働いたことがありません。もし私がこのような要件を取得すれば、私は本当にそれを解決する方法を知らない。

どのようにすればいいのですか?

+7

'System.out.print'(' PrintWriter')は2行目から4行目をサポートしていないため、エラーがあります。 – SJuan76

+11

_System.out.print()はエラーをスローしません_本当ですか?まあ、あなたの例では、最初の行以外のすべての行にエラーがスローされます。コンマは 'System.out.print()'で受け入れられません。カンマは異なるパラメータを区切るために使われ、 'System.out.print()'は1パラメータを受け取ります。文字列間の連結は '+'演算子。 – BackSlash

+1

は '、' a typoですか? '+'の代わりに? – pinkpanther

答えて

11

System.outは、ちょうどPrintStreamのインスタンスです。そのJavaDocを確認することができます。その可変性はmethod overloadingに基づいています(名前は同じですが、パラメータが異なる複数のメソッド)。

この印刷ストリームは、その出力をいわゆるstandard outputに送信しています。あなたの質問に


あなたはvariadic functionsと呼ばれる技術(または可変引数)を言及します。残念ながらそれはPrintStream#printでサポートされていないので、これを別のものと間違えている必要があります。しかし、Javaでこれらを実装するのは非常に簡単です。 Just check the documentation.


そして、あなたはJavaは非文字列変数に"foo" + 1 + true + myObjを連結する方法を知っているか興味があるならば、それは主にJavaコンパイラの責任です。

連結に関連する変数がない場合、コンパイラは単純にその文字列を連結します。関係する変数がある場合、連結はStringBuilder#appendチェーンに変換されます。結果のバイトコードには連結命令はありません。すなわち、+演算子(文字列連結について話すとき)は、コンパイル中に解決されます。 (自分の#toString経由intIntegerクラスのメソッドを経由して、Booleanクラスのメソッドを経由してboolean、オブジェクト、...)

のJavaのすべての種類は文字列に変換することができます。興味のある場合は、StringBuilderのソースコードをチェックすることができます。


UPDATE:私は自分自身興味があったし、私の例System.out.println("foo" + 1 + true + myObj)がにコンパイルするもの(javapを使用して)確認。結果:

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

完全なものにするには、引数のオーバーロードが許可されている間に、戻り値のオーバーロードは許可されません。 +1。 – fge

+0

私はなぜこの答えが間違っていたのかを知りません。 'system.out.print'は可変個の引数を取るわけではありません。単純に単一の文字列を取ります。 – Devolus

+2

@Devolusかもしれませんが、私はそれをサポートしていないと言っているのでしょうか? downvotingの前にお読みください。 –

0

そのすべてについてMethod Overloading

は、オブジェクトを印刷して、行を終了します:あなたがオブジェクトを渡すと

println() method

内の各データ型に対して個別の方法があります。このメソッドは、最初にString.valueOf(x)を呼び出して印刷オブジェクトの文字列値を取得し、print(String)を呼び出してからprintln()を呼び出すように動作します。 println(String型x)の方法を、対応する

を呼び出す:あなたはプリミティブ型を渡すと

:あなたは文字列を渡すとプリミティブ型メソッド対応

呼び出します

0

printf(String format, Object... args)メソッドと混同していると思います。最初の引数はフォーマット文字列です。これは必須です。残りはObjectの任意の数値を渡すことができます。

println()の両方の方法には、そのようなオーバーロードはありません。

2

System.put.print...()が可変数の引数を取るかのように見えますが、それはそうではありません。密接に見ると、文字列は単純に連結され、任意の文字列で同じことができます。唯一起こっているのは、渡しているオブジェクトが、toString()メソッドを呼び出すjavaによって暗黙的に文字列に変換されていることです。これを行おうと

それは失敗します。ここでの暗黙的な変換が行われていないため

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

理由は、あります。

あなたは

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

にそれを変更した場合しかし、それは動作し、これは、同様System.put.print...()を使用したときに何が起こるかです。

あなたがC printfのようなものをmimimcするためにJavaで可変個の引数を実装したい場合は、このようにそれを宣言することができます。

で、ここで起こる文字列の配列が渡されていることは何ですか
public void t(String s, String ... args) 
{ 
    String val = args[1]; 
} 

提供される引数の長さここでJavaはあなたのための型チェックを行うことができます。

あなたが本当にのprintfをしたいなら、あなたはこのようにそれをしなければならない。

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

は、その後、あなたはそれに応じて引数をキャストまたは解釈する必要があります。

0

何を印刷するかを選択する限り、何でも文字列に変換できます。Objet.toString()は、デフォルトのダム文字列:package.classname + @ + object numberを返すことができるので、要件は非常に単純です。

印刷メソッドでXMLまたはJSONのシリアル化が返される場合、toString()の基本的な結果は受け入れられません。メソッドが成功したとしても。

は、ここでJavaが何か[email protected]を出力します

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

ダムできることを示すために、単純な例です!あなただけの2人の文字列のメンバーを持っており、これは

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

(またはかなりそれがdebbugerでどのように表示されるか)を印刷するために実装することができたとしても

0

システムの操作方法を理解することは非常に敏感なポイントです。 out.print。 最初の要素がStringの場合、プラス(+)演算子はStrig連結演算子として機能します。最初の要素が整数プラス(+)の場合、演算子は数学演算子として動作します。

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

明らかに、コンパイラの開発者は、スマートさを追加したとは思うが、明らかにコンパイラは混乱してしまった。実際に追加すべき真のスマートさは、議論全体を見て、+演算子を一貫して解釈することです。たとえば、System.out.println(1+2+"hello"+3+4);は、3hello34の代わりに3hello7を出力する必要があります。

関連する問題