e.getMessage()和e.getLocalizedMessage()之间的区别

Dev*_*ath 73 java android

  • 我正在使用这两种方法来获取catch块在执行错误处理时抛出的消息
  • 他们两个都从错误处理中得到了消息,但这两者究竟有什么不同
  • 我从网上搜索了一下,从这里得到了这个答案

Java Exceptions从Throwable继承了它们的getMessage和getLocalizedMessage方法(参见相关链接).不同之处在于子类应覆盖getLocalizedMessage以提供特定于语言环境的消息.例如,您正在将来自美国英语公司/团队的代码调整为英国 - 英语组的成像.您可能希望创建自定义的Exception类,该类覆盖getLocalizedMessage以更正拼写和语法,以及将使用您的代码的用户和开发人员可能期望的内容.这也可以用于Exception消息的实际翻译.


问题 ::

  • 这是否意味着language specific实施?就像我使用e.getLocalizedMessage()我的应用程序一样English- 错误将被抛入English,如果我使用我的应用程序Spanish- 然后错误将被抛入Spanish

  • 需要一些明确的解释,我可以在何时何地使用这些方法

dgm*_*dgm 64

正如大家上面提到的那样 -

据我所知,getMessage()返回异常的名称.getLocalizedMessage()以用户的本地语言(中文,日文等)返回例外的名称.为了使这项工作,您调用的类getLocalizedMessage()必须覆盖该getLocalizedMessage()方法.如果没有,则调用其中一个超类的方法,默认情况下只返回getMessage的结果.

除此之外,我想介绍一些代码段来解释如何使用它.

如何使用它

Java没有什么神奇之处,但确实提供了一种让我们的生活更轻松的方法.要getLocalizedMessage()有效使用,我们必须覆盖默认行为.

import java.util.ResourceBundle;

public class MyLocalizedThrowable extends Throwable {

    ResourceBundle labels = ResourceBundle.getBundle("loc.exc.test.message");

    private static final long serialVersionUID = 1L;
    public MyLocalizedThrowable(String messageKey) {
        super(messageKey);
    }

    public String getLocalizedMessage() {
        return labels.getString(getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

java.util.ResourceBundle 用来做本地化.

在此示例中,您必须在loc/exc/test路径中放置特定于语言的属性文件.例如:

message_fr.properties(包含一些键和值):

key1=this is key one in France
Run Code Online (Sandbox Code Playgroud)

message.properties(包含一些键和值):

key1=this is key one in English
Run Code Online (Sandbox Code Playgroud)

现在,让我们假设我们的异常生成器类就像

public class ExceptionGenerator {

    public void generateException() throws MyLocalizedThrowable {
        throw new MyLocalizedThrowable("key1");
    }
}
Run Code Online (Sandbox Code Playgroud)

而主要的课程是:

public static void main(String[] args) {
    //Locale.setDefault(Locale.FRANCE);
    ExceptionGenerator eg = new ExceptionGenerator();

    try {
        eg.generateException();
    } catch (MyLocalizedThrowable e) {
        System.out.println(e.getLocalizedMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,如果您在"英语"环境中执行,它将返回"英语"键值.如果将local设置为France,则将从message_fr文件中获取输出.

什么时候使用它

如果您的应用需要支持l10n/i18n,则需要使用它.但是大多数应用程序都不需要,因为大多数错误消息不是针对最终客户,而是针对支持工程师/开发工程师.

  • "根据我的理解,getMessage()返回异常的名称." 这是错的.Exception的名称可以从`e.getClass().getSimpleName()`中找到.`new NullPointerException().getMessage()`返回"null",而不是"NullPointerException". (3认同)
  • 但这里的陷阱是该方法实际上并不采用区域设置,因此并不总是可以获得用户的区域设置。特别是,此答案中异常的实现方式只会正确本地化 GUI 应用程序的异常。对于服务器端应用程序,JVM 的默认区域设置与用户的默认区域设置不同,因此最好的策略是永远不要调用 ResourceBundle.getBundle(String) 并始终提供用户的实际区域设置。(例如,对于 Web 应用程序,您通常会在标头中收到有关用户区域设置的信息。) (2认同)

Sub*_*der 6

这真的很令人惊讶 - 检查Throwable.java类的 openJDK 7 代码。

的实现getLocalizedMessage是 -

390     public String getLocalizedMessage() {
391         return getMessage();
392     }
Run Code Online (Sandbox Code Playgroud)

和实施getMessage是 -

376     public String getMessage() {
377         return detailMessage;
378     }
Run Code Online (Sandbox Code Playgroud)

130     private String detailMessage;
Run Code Online (Sandbox Code Playgroud)

两种方法的实现都没有变化,但文档。

  • 文档明确指出“子类可能会覆盖此方法以生成特定于语言环境的消息。对于不覆盖此方法的子类,默认实现返回与 getMessage() 相同的结果。” (18认同)

rad*_*dai 5

不。它绝对不意味着特定于语言的实现。它意味着使用国际化(又名 i18n)机制的实现。有关资源包是什么以及如何使用它们的更多详细信息,请参阅此页面。

要点是,您将任何文本放入资源文件中,其中您有很多(每个区域设置/语言/等一个),并且您的代码使用一种机制在正确的资源文件中查找文本(我提供的链接详细介绍了)。

至于何时何地使用它,完全取决于你。通常,只有当您想向非技术用户(他们可能不太懂英语)提供例外时,您才会担心这一点。例如,如果您只是写入日志(通常只有技术用户才能阅读,因此不是常见的 i18n 目标),您会这样做:

try {
   somethingDangerous();
} catch (Exception e) {
   log.error("got this: "+e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)

但如果您打算在屏幕上显示异常消息(例如,作为小对话框),那么您可能希望以本地语言显示该消息:

try {
   somethingDangerous();
} catch (Exception e) {
   JOptionPane.showMessageDialog(frame,
    e.getLocalizedMessage(),
    "Error",  <---- also best be taken from i18n
    JOptionPane.ERROR_MESSAGE);
}
Run Code Online (Sandbox Code Playgroud)