增强型MessageFormat?

4

我已经使用MessageFormat.format()一段时间了,但有一件事情让我感到烦恼。

每当您在消息中声明参数时,您必须知道映射参数的位置。例如:

MessageFormat.format("{0} is annoying {1}.", "this", "indeed")

是否有一种类似于MessageFormat的类,除了让您完全省略参数声明中的参数位置并将其默认为其在消息中的位置之外,在其他方面与其相同,以便第一个参数映射到第一个参数,第二个参数映射到第二个参数,依此类推?例如:

MessageFormat.format("{} is much better{}.", "this", "indeed")

我认为log4j的后续版本也有类似的功能,但我只需要格式化类。

新年快乐!

编辑: 我需要这个功能来进行断言,所以它真的只是用于内部使用,但我感谢您对MessageFormat工作方式的见解。

3个回答

8
你应该使用Formatter或其前端String.format,而不是直接拼接字符串。你可以这样做:
String.format("%s is much better %s", "this", "indeed");
String.format("%1$s provides positional formatting %2$s", "this", "indeed");

7
提供您所请求的内容将打败 MessageFormat 的主要目的之一,即国际化(I18N)和本地化(L10N)。也就是说,不同的自然语言可能使用不同的单词顺序来组成“相同”的句子。 MessageFormat 允许您的代码在设置的顺序中强制提供一组参数,然后在为每种语言编写本地化自然语言字符串时变化插值顺序 - 您可能会在Java Properties文件中定义,这些文件以适当命名的类加载,使用ResourceBundle

典型的工作流程涉及首先使用您的主要母语(例如英语)编写用户可见的消息,然后针对要本地化软件的每种其他语言,定义将这些参数化消息翻译成目标语言的并行属性文件,并调整输入参数以适合适当的句子结构。

如果您不需要任何该功能,请尝试只使用 String#format()


虽然使用 Formatter/String.format 不会剥夺本地化消息的能力,但对于正确的思路加一分。 - C. K. Young
虽然在String#format()中使用位置索引参数的语法很难正确使用,但这是真的。 - seh
有趣的选项是来自Slf4j库的MessageFormatter。它声称比MessageFormat快10倍,而且不需要考虑Locale的特定性。 - Dimitar II
3
MessageFormat 需要进行更新:它使用了 StringBuffers 和带格式的索引字段,甚至在 Java 10 中也不支持 Java Time API。 - dmatej

2

我模糊地记得曾经遇到过这样的事情。但是,我想不起来它在哪里了。不过,有一些解决方案可以使用。例如,你可以像现在一样将格式字符串存储在外部包中,但是不要使用MessageFormat字符串,而是使用String.format()支持的printf风格的字符串。这些字符串允许位置参数符号,但也允许传统的“按照参数列表中的顺序”。

然而,请注意,必须指定索引的原因是国际化。如果您决定将格式字符串移动到外部消息包中,通常是为了允许本地化(到其他语言),其中本地化句子中单词的顺序可能与参数列表中字符串的顺序不匹配。

总之,最好坚持指定顺序。如果你发现你的应用程序非常成功,并且你在其他国家有令人难以置信的销售机会,如果你只能让所有消息以他们的语言输出,那么这会使事情变得更容易...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接