Різниця між e.getMessage () та e.getLocalizedMessage ()


84
  • Я використовую ці обидва методи, щоб отримати повідомлення, викинуте блоком catch під час обробки помилок
  • Обидва вони отримують мені повідомлення від обробки помилок, але чим саме ці два відрізняються
  • Я здійснив пошук в Інтернеті і придумав цю відповідь звідси

Винятки Java успадковують їхні методи getMessage та getLocalizedMessage від Throwable (див. Відповідне посилання). Різниця полягає в тому, що підкласи повинні замінювати getLocalizedMessage, щоб надати повідомлення про конкретну місцевість. Наприклад, зображення того, що ви адаптуєте код американсько-англомовної компанії / групи до британсько-англійської. Можливо, ви захочете створити власні класи винятків, які замінюють getLocalizedMessage, щоб виправити написання та граммери відповідно до того, що можуть очікувати користувачі та розробники, які будуть використовувати ваш код. Це також можна використовувати для фактичного перекладу повідомлень про винятки.


Запитання ::

  • Це означає language specificреалізації? наприклад, якщо я використовую, e.getLocalizedMessage()наприклад, свій додаток English- помилка буде введено English, якщо я використовую свій додаток Spanish- тоді буде введено помилкуSpanish

  • Потрібне чітке пояснення щодо того, де і коли я можу використовувати ці методи для свого використання


1
Так, це означає реалізації конкретної мови (мови, культури). Що поганого в офіційній документації ?
стандартна локалізація

Відповіді:


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

За замовчуванням він поверне значення ключа "English", якщо ви виконуєте в середовищі "English". Якщо ви встановите для місцевого значення Францію, ви отримаєте вихідні дані з файлу message_fr.

Коли його використовувати

Якщо ваша програма повинна підтримувати l10n / i18n, вам потрібно її використовувати. Але більшість програм не потрібно, оскільки більшість повідомлень про помилки стосуються не кінцевого замовника, а інженера підтримки / інженера-розробника.


6
"Наскільки я розумію, getMessage () повертає ім'я винятку." Це просто неправильно. Назва винятку знайдено з e.getClass().getSimpleName(). new NullPointerException().getMessage()повертає "null", а не "NullPointerException".
Філіп Уайтхаус,

Однак пастка тут полягає в тому, що метод насправді не приймає локаль, тому не завжди вдається отримати локаль користувача. Зокрема, спосіб реалізації винятку у цій відповіді лише належним чином локалізує виняток для програми GUI. Для серверної програми локальний стандарт JVM за замовчуванням не збігається з користувальницьким, тому найкраща політика - ніколи не викликати ResourceBundle.getBundle (String) і завжди вказувати фактичну локаль користувача. (Наприклад, у веб-програмах ви зазвичай отримуєте інформацію про локаль користувача в заголовку.)
Trejkaz

6

Це справді дивно - Перевірте код openJDK 7 класу Throwable.java .

Реалізація getLocalizedMessage-

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

І реалізація getMessage-

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

І

130     private String detailMessage;

Існує ніяких змін у впровадженні обох методів, окрім документації.


15
У документації чітко сказано: "Підкласи можуть замінити цей метод, щоб створити повідомлення про локаль. Для підкласів, які не замінюють цей метод, реалізація за замовчуванням повертає той самий результат, що і getMessage ()."
crazy4jesus

2

немає. це однозначно не означає реалізації конкретної мови. це означає реалізації, що використовують механізм інтернаціоналізації (він же 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() 

Повертає рядок детального повідомлення цього файлу, що передається.

public String getLocalizedMessage() 

Створює локалізований опис цього викидного файлу. Підкласи можуть замінювати цей метод, щоб створити повідомлення про конкретну місцевість. Для підкласів, які не замінюють цей метод, реалізація за замовчуванням повертає той самий результат, що і getMessage().

У вашому випадку e - це не що інше, як об'єкт виключення ...

getLocalizedMessage() вам потрібно замінити і надати власне повідомлення, тобто значення локалізованого повідомлення.

Наприклад ... якщо є виняток нульового вказівника ...

Друкуючи e, відображатиметься нуль

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

Створює локалізований опис цього викидного файлу. Підкласи можуть замінювати цей метод, щоб створити повідомлення про конкретну місцевість. Для підкласів, які не замінюють цей метод, реалізація за замовчуванням повертає той самий результат, що і getMessage ().

У вашому випадку e - це не що інше, як об'єкт виключення ...

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

Наприклад ... якщо є виняток нульового вказівника ...

Друкуючи e, відображатиметься нуль

e.getMessage() ---> NullPointerException 

Читати далі ...


-2

На моє розуміння, getMessageповертає назву винятку.

getLocalizedMessage повертає ім'я винятку місцевою мовою користувача (китайською, японською тощо).

Для того, щоб це працювало, клас, до якого ви телефонуєте, getLocalizedMessageповинен замінитиgetLocalizedMessage метод.

Якщо цього не сталося, викликається метод одного із суперкласів, який за замовчуванням просто повертає результат getMessage.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.