Java 为什么字符串是';s格式(对象…参数)定义为静态方法?
我想知道为什么Java 5和更高版本在类字符串中使用静态方法提供printf样式的格式化程序,如下所示: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
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);