27

Java 5以降では、次のようなクラスStringの静的メソッドを使用してprintfスタイルのフォーマッタが提供されるのはなぜだろうか。

public static String format(String format, Object... args)

それ以外の

public String format(Object... args)

の代わりに"%02d".format(5)getに書き込むことができるようにします。05String.format("%02d", 5)

Stringクラスを変更できるとしたら、次のように追加できます。

public String format(Object... args) {
    return format(this, args)
}

同じ結果を得るには。

C#では、インスタンスメソッドの代わりに静的メソッドも使用されていることがわかりました。

なぜ彼らがこれをやろうと決心したのだろうかと思いますが、私は説明に来ませんでした。インスタンスは文字列の新しいインスタンスをメソッドtrimしてsubstring返すので、。を使用して同じことを行う必要がありformatます。

さらに、DateFormatクラスはこれも使用します。

public final String format(Date date)

日付のフォーマット用。したがって、DateFormatのインスタンスをフォーマッターと見なすと、Stringのインスタンスもフォーマッターとして使用できます。

何か案は?

4

14 に答える 14

13

おそらく、メソッドが呼び出され"%02d".format(5)ているオブジェクトがフォーマット文字列であることを意味しているようです。format

この場合、フォーマット文字列もたまたまであるStringため、その点をさらに進めると、すべてのsがフォーマット文字列であると主張することができStringます。

おそらくこれは、一般的にStringすべてのsについて暗黙のステートメントを作成するのではなく、クラスの静的メソッドを使用して文字列をフォーマットできると言うことで回避できます。String

于 2009-04-27T04:50:18.263 に答える
7

私はJavaの設計者ではありませんが、Javaを静的にする明確な理由を1つ挙げることができます。

Java 5には多くの機能がありますが、注目すべき2つは次のとおりです。

  • クラス内からクラス名をリストせずに静的メソッドを簡単に使用できるようにする「importstatic」コマンドを実行する機能。
  • printfsを簡単に実行する静的ユーティリティメソッド。

メソッドを静的にすることで言えることは素晴らしいことですが"bla: %d".format("foo"),、Cプログラマーにとって非常に馴染みのあるすっきりとした方法でフォーマットを使用することができますprintf()

import static java.lang.String.format;

public class Demo {

   public void Test() {

      //Do some stuff

      format("Hey, this is easy to read!");

   }
 }

そしてそれが理由です!静的インポートを使用することにより、printfsはCの場合とほぼ同じように見えます。

于 2009-04-27T06:54:14.957 に答える
5

主な理由は、おそらくJavaの設計者がStringのインターフェースにあまり多くのものを追加したくないということです。それをメンバー関数にすることは、それを文字列に置くことを意味するでしょう。非静的メソッドはStringオブジェクト上にある必要があることに注意してください。

2番目の理由は、静的フォーマットがCのprintfとの類似性を維持していることです。これは、printf(FORMAT、ARG1、ARG2 ...)のように見えます。

もう1つの理由は、フォーマットがオーバーロードされていることです。最初のパラメーター(文字列の前)としてロケールを使用するバージョンがあるため、文字列オブジェクトでこれを行うのは難しいでしょう。

于 2009-04-27T04:46:49.067 に答える
3

"%02d" .format(5)は、 "%02d"がフォーマット5を使用してフォーマットされているように見えますが、その逆ではありません。また、ほとんどの文字列はフォーマットとして適切ではないため( "hello world" .format(5)?)、メソッドはほとんどの文字列オブジェクトに対して例外をスローする必要があります。

于 2009-04-27T04:57:12.163 に答える
3

回答はFormatメソッドの責任です。

「フォーマットはフォーマット文字列で動作する」と言うよりも、「フォーマット文字列はフォーマットメソッドに入力される」と言う方が論理的で直感的です。これは、「通常」、設計時に知られているフォーマット文字列をFormatに渡すためです。対照的に、Trimの場合、「通常」、設計時に値が不明な変数文字列を渡します。

したがって、formatメソッドを静的にして、コードの読み取りをより直感的にします。以下を見てください(C#)。

answer = String.Format("This is format string : {0}", someValue); 
//More readable to me

answer = "This is format string : {0}".Format(someValue);

編集:C#のサンプルコードを使用しましたが、Javaにもうまく適用されます。C#構文の使用に-ve票を獲得しました!

于 2009-04-27T05:08:25.473 に答える
2

私は本当にformatStringのインスタンスメソッドでなければならないと思います。

  • Python:
    2.6: "%s"%( "Hello")を出力します
    3.0:print( "{0}"。format( "Hello"))
  • Scala:
    2.7.6:println( "%s" .format( "Hello"))
于 2010-01-17T11:28:52.490 に答える
0

String.format(strfmt、objects)の代わりにstrfmt.format(objects)を呼び出す

  • 静的ヘルパーへの呼び出しではなく、オブジェクト指向の呼び出しです。
  • タイプするのが短い。
  • 引数が1つ少ないので、より単純です。
  • コード補完で使用する方が簡単です。フォーマット文字列から始めて、を押した場合。IDEのオプションとしてformat()を取得します。
  • String.format(strfmt、objects)は、誤ってstrfmt.format(text、objects)と呼ばれる可能性があり、見た目どおりに機能しません。
于 2009-04-27T20:40:29.853 に答える
0

おそらく、それが便宜上存在する「ユーティリティ」関数であることを示すためですが、これは実際には文字列の組み込み関数ではありません。つまり、文字列"%02d"はフォーマットを表す方法ですが、実際にはフォーマットを行いません。

このメソッドは文字列のフォーマットを便利にするために存在しますが、Formatter(実際のフォーマットを実行する)は他のタイプのオブジェクト(日付など)もフォーマットできます。

于 2009-04-27T04:49:56.237 に答える
0

呼び出しがCのsprintf機能を彷彿とさせるからです。

于 2009-04-27T05:10:15.813 に答える
0

おそらくStringは不変であるため、このメソッドはStringインスタンスの新しいインスタンスを作成して返す必要があります。メソッドが静的であると宣言されていない場合は、呼び出されたStringインスタンスを変更することを期待するでしょう。

于 2009-04-27T05:37:52.317 に答える
0

Javaが、C ++であっても、他のものと同様の構造を作成することは必須ではないと思います。開発者がそれを受け入れるので、採用されるものはすべてそうでなければなりません。さらに、「他のものと似たものにした」などの引数は、インスタンスメソッドバージョンを作成するだけでなく、プリミティブラッパーを使用してこれを行う理由を説明していません(インスタンスtoString()メソッドに加えて、静的バージョンがあります) )。

これは私が思うことです:

通常の場合、両方の形式は同等ですが、次のようなものがあるとします。

String invalidFormat = "%invalid"; // or something else that is invalid

そして、私たちは次のように呼びます。

String.format(invalidFormat, anything);
// "anything" is indeed anything....

無効なものが引数になり、JavaはIllegalArgumentExceptionのインスタンスをスローすることでこれを明確にします(Formatterの場合でも、多くの種類があります)。

ただし、次のようなものです。

invalidFormat.format(anything);

無効なものはもはや引数ではありません。問題は、呼び出されたインスタンスにあるため、probabyは「無効な状態」(完全に異なる使用法を持つJavaの「IllegalStateException」ではない)としてより適切に記述されます。ただし、文字列は不変であるため、このいわゆる「状態」は変更されません。したがって、有効な単純な文字列であっても、形式としては常に無効のままになります。

これを、たとえばjava.lang.Longと比較してください。toStringの両方のバージョンが例外をスローすることはないため、どちらも同等です。

于 2009-04-27T06:31:02.890 に答える
0
answer = String.Format("This is format string : {0}", someValue); 
//More readable to me

answer = "This is format string : {0}".Format(someValue);
于 2011-03-12T07:06:28.823 に答える
0

ただ悪いデザイン。pythonerはそれが苦痛だと感じています。

于 2016-10-13T02:07:48.837 に答える
-1

C#では、文字列は不変です。これはJavaにも当てはまると思います(100%確実ではありません)。したがって、formatメソッドを呼び出して文字列を変更するのではなく、書式設定を含む新しい文字列を返すだけです。これにより、インスタンスレベルのメソッドではなく、クラスレベルのメソッドになり、静的になります。拡張関数を使用してC#でインスタンスレベルのファサードを追加できますが、これは静的関数の上に単に構文上の糖衣構文です。

于 2009-04-27T04:58:15.327 に答える