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


84
  • 我在执行错误处理时使用这两种方法来获取catch块抛出的消息
  • 他们俩都从错误处理中得到了我的消息,但是两者的区别到底是什么
  • 我从互联网上搜索了一些内容,然后从这里想出了这个答案

Java异常从Throwable继承其getMessage和getLocalizedMessage方法(请参见相关链接)。区别在于子类应重写getLocalizedMessage以提供特定于语言环境的消息。例如,想象一下您正在将代码从一个说英语的公司/组改编为一个英语-英语组。您可能需要创建自定义Exception类,该类将覆盖getLocalizedMessage,以将拼写和语法正确化为将使用您的代码的用户和开发人员所期望的内容。这也可以用于异常消息的实际翻译。


问题::

  • 这意味着language specific实现吗?就像如果我使用e.getLocalizedMessage()我的应用程序English-错误将被抛出English,如果我使用我的应用程序Spanish-那么错误将被抛出Spanish

  • 需要在何时何地可以使用这些方法的清楚说明


1
是的,这意味着特定于语言环境(语言,文化)的实现。有什么不对的正式文件
默认语言环境

Answers:


71

就像上面每个人都提到的

据我了解,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());
    }
}

java.util.ResourceBundle 用于进行本地化。

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

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

key1=this is key one in France

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

key1=this is key one in English

现在,让我们假设我们的异常生成器类类似于

public class ExceptionGenerator {

    public void generateException() throws MyLocalizedThrowable {
        throw new MyLocalizedThrowable("key1");
    }
}

主要类别是:

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());
    }
}

默认情况下,如果您在“英语”环境中执行,它将返回“英语”键值。如果将本地设置为法国,则将从message_fr文件获取输出。

什么时候使用

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


6
“据我所知,getMessage()返回异常的名称。” 这是错误的。可以从找到异常的名称e.getClass().getSimpleName()new NullPointerException().getMessage()返回“ null”,而不是“ NullPointerException”。
菲利普·怀特豪斯'02

但是,这里的陷阱是该方法实际上并没有采用语言环境,因此并非总是能够获得用户的语言环境。特别是,此答案中的异常已实现的方式仅会为GUI应用程序正确定位异常。对于服务器端应用程序,JVM的默认语言环境与用户的语言环境不同,因此最好的策略是永远不要调用ResourceBundle.getBundle(String)并始终提供用户的实际语言环境。(例如,对于Web应用程序,通常会在标头中接收有关用户的语言环境的信息。)
Trejkaz,

6

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

实现getLocalizedMessage是-

390     public String getLocalizedMessage() {
391         return getMessage();
392     }

的实现getMessage是-

376     public String getMessage() {
377         return detailMessage;
378     }

130     private String detailMessage;

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


15
该文档明确指出:“子类可以重写此方法以生成特定于语言环境的消息。对于不重写此方法的子类,默认实现返回与getMessage()相同的结果。”
fool4jesus 2015年

2

没有。它绝对不是特定于语言的实现。它表示使用国际化(aka i18n)机制的实现。看到这个页面有关什么是资源包以及如何使用它们的更多详细信息,。

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

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

try {
   somethingDangerous();
} catch (Exception e) {
   log.error("got this: "+e.getMessage());
}

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

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

2
public String  getMessage() 

返回此throwable的详细消息字符串。

public String getLocalizedMessage() 

创建此throwable的本地化描述。子类可以重写此方法,以生成特定于语言环境的消息。对于不覆盖此方法的子类,默认实现返回与相同的结果getMessage()

在您的情况下,e只是异常的对象...

getLocalizedMessage() 您需要覆盖并提供您自己的消息,即本地化消息的含义。

例如...如果存在空指针异常...

通过打印e将显示null

e.getMessage() ---> NullPointerException

2

这就是Throwable.java类必须说的。也许可以帮助某人:

/**
 * Returns the detail message string of this throwable.
 *
 * @return  the detail message string of this {@code Throwable} instance
 *          (which may be {@code null}).
 */
public String getMessage() {
    return detailMessage;
}

/**
 * Creates a localized description of this throwable.
 * Subclasses may override this method in order to produce a
 * locale-specific message.  For subclasses that do not override this
 * method, the default implementation returns the same result as
 * {@code getMessage()}.
 *
 * @return  The localized description of this throwable.
 * @since   JDK1.1
 */
public String getLocalizedMessage() {
    return getMessage();
}

-2

据我了解,getMessage返回异常的名称。getLocalizedMessage以用户的本地语言(中文,日语等)返回异常的名称。为了使此工作正常进行,您正在调用getLocalizedMessage的类必须已重写getLocalizedMessage方法。如果没有,则调用其中一个超类的方法,该方法默认情况下仅返回getMessage的结果。

因此,在大多数情况下,结果将是相同的,但在某些情况下,它将以运行程序的区域的语言返回异常名称。

这是否意味着特定于语言的实现?就像如果我使用e.getLocalizedMessage()例如我的英语应用程序-错误将以英语抛出,如果我使用西班牙语的应用程序-则将以西班牙语抛出错误

public String 
getMessage() 

Returns the detail message string of this throwable.





public String 
getLocalizedMessage() 

创建此throwable的本地化描述。子类可以重写此方法,以生成特定于语言环境的消息。对于不覆盖此方法的子类,默认实现返回与getMessage()相同的结果。

在您的情况下,e只是异常的对象...

getLocalizedMessage() u need to override and give your own message i.e 
the meaning for localized message. 

例如...如果存在空指针异常...

通过打印e将显示null

e.getMessage() ---> NullPointerException 

阅读更多...


-2

据我了解 getMessage返回异常的名称。

getLocalizedMessage 以用户的本地语言(中文,日语等)返回异常的名称。

为了使此工作正常进行,您正在调用的类getLocalizedMessage必须已覆盖getLocalizedMessage方法。

如果没有,则调用其中一个超类的方法,默认情况下,该方法仅返回的结果getMessage

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.