Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么字符串是';s格式(对象…参数)定义为静态方法?_Java_String_Format_Printf - Fatal编程技术网

Java 为什么字符串是';s格式(对象…参数)定义为静态方法?

Java 为什么字符串是';s格式(对象…参数)定义为静态方法?,java,string,format,printf,Java,String,Format,Printf,我想知道为什么Java 5和更高版本在类字符串中使用静态方法提供printf样式的格式化程序,如下所示: public static String format(String format, Object... args) 而不是 public String format(Object... args) 这样我们就可以编写%02d.format(5)来获得05,而不是String.format(“%02d”,5) 我想象如果我可以修改String类,我可以添加以下内容: public Str

我想知道为什么Java 5和更高版本在类字符串中使用静态方法提供printf样式的格式化程序,如下所示:

public static String format(String format, Object... args)
而不是

public String format(Object... args)
这样我们就可以编写
%02d.format(5)
来获得
05
,而不是
String.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的实例看作格式化程序,字符串的实例也可以用作格式化程序。
有什么想法吗?

主要原因可能是Java的设计者不想给String的接口添加太多东西。将其作为成员函数意味着将其放在字符串上。请记住,非静态方法必须位于String对象上

第二个原因是静态格式与C的printf保持相似, 看起来像printf(格式,ARG1,ARG2…)


另一个原因是格式过载:有一个版本将locale作为第一个参数(在字符串之前),因此在字符串对象上执行此操作将很棘手。

可能是为了表明它是一个“实用”函数,存在于方便中,但实际上不是字符串的固有函数。也就是说,字符串
“%02d”
是一种表示格式的方法,但它实际上不进行任何格式化

该方法的存在是为了方便地格式化字符串,但是(执行实际格式化的)也可以格式化其他类型的对象(日期等)。

可能是
%02d。格式(5)
似乎暗示调用
格式
方法的对象是格式字符串

在本例中,格式字符串碰巧也是
字符串
,因此进一步说明这一点,可以认为所有
字符串
都是格式字符串


如果说
String
类中的静态方法可用于格式化字符串,而不是对所有
String
进行隐式声明,则可能可以避免这种情况。

%02d。格式(5)看起来像是使用格式5格式化的“%02d”,而不是相反的格式。另外,大多数字符串不适合作为格式(“hello world.format(5)”,因此该方法应该为大多数字符串对象抛出异常。

在C#中。我认为在Java中也是如此(对此不是100%确定)。因此,您并不是通过对字符串调用format方法来更改字符串,而是只返回一个带有格式的新字符串。这使它成为类级方法而不是实例级方法,因此它是静态的。您可以使用扩展函数在C#中添加实例级facade,但这只是静态函数之上的语法糖。

答案由Format方法负责

至少对我来说,说“format string是format方法的输入”比说“format对format string进行操作”更符合逻辑,更直观。这是如此,因为我们“通常”将设计时已知的格式字符串传递给格式化。相反,对于Trim,我们“通常”传递在设计时未知值的变量字符串

所以,使格式化方法静态化,使代码读取更加直观。看下面的(C#)


编辑:尽管我使用了C#示例代码,但它很好地适用于Java。我投票赞成使用C#语法

仅仅是因为调用让人想起C的
sprintf
函数。

可能是因为String是不可变的,因此此方法必须创建并返回String实例的新实例。如果该方法未声明为静态,则可能希望修改它调用的字符串实例。

< P>我认为java与任何其他东西(甚至C++)都有类似的构造,这不是强制性的。任何被采纳的东西都必须如此,因为开发者接受它。此外,诸如“它们使其与其他方法类似”之类的参数并不能解释为什么它们不只是生成实例方法版本,而是使用基本包装器(除了实例toString()方法之外,它们还有静态版本)

我是这样想的:

在正常情况下,这两种形式是等效的,但假设我们有如下情况:

String invalidFormat = "%invalid"; // or something else that is invalid
invalidFormat.format(anything);
然后我们称之为:

String.format(invalidFormat, anything);
// "anything" is indeed anything....
无效参数成为参数,Java通过抛出IllegalArgumentException实例(即使在Formatter中,也有很多种)来澄清这一点

但是,在以下情况下:

String invalidFormat = "%invalid"; // or something else that is invalid
invalidFormat.format(anything);
无效的那个不再是论点。现在的问题在于调用它的实例,因此最好将其描述为“无效状态”(而不是Java的“IllegalStateException”,它有完全不同的用法)。但是因为字符串是不可变的,所以这个所谓的“状态”永远不会改变,所以它作为一种格式总是无效的,即使它是一个有效的简单字符串


将其与java.lang.Long进行比较。toString的两个版本都不会抛出任何异常,因此它们都是等效的。

虽然我不是Java的设计者,但我可以告诉你一个明确的理由,让它成为静态的

Java 5提供了许多功能,但值得注意的是:

  • 执行“导入静态”命令的能力,该命令允许在类内轻松使用静态方法,而无需列出它们的类名
  • 一种易于执行printfs的静态实用程序方法
虽然能够说
“bla:%d”.format(“foo”),
通过使方法静态,您可以使用form 2.6: print "%s" % ("Hello") 3.0: print("{0}".format("Hello")) 2.7.6: println("%s".format("Hello"))
answer = String.Format("This is format string : {0}", someValue); 
//More readable to me

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