Różnica między e.getMessage () i e.getLocalizedMessage ()

85
  • Używam tych obu metod, aby uzyskać komunikat wyrzucony przez blok catch podczas wykonywania obsługi błędów
  • Obydwa dają mi komunikat z obsługi błędu, ale czym dokładnie się te dwa różnią
  • Wyszukałem trochę w Internecie i znalazłem tę odpowiedź stąd

Wyjątki Java dziedziczą metody getMessage i getLocalizedMessage z Throwable (zobacz powiązany link). Różnica polega na tym, że podklasy powinny nadpisywać getLocalizedMessage, aby dostarczyć komunikat specyficzny dla ustawień regionalnych. Na przykład wyobrażenie sobie, że adaptujesz kod z amerykańsko-anglojęzycznej firmy / grupy do grupy brytyjsko-angielskiej. Możesz chcieć stworzyć niestandardowe klasy Exception, które nadpisują getLocalizedMessage, aby poprawić pisownię i gramaturę zgodnie z oczekiwaniami użytkowników i programistów, którzy będą używać twojego kodu. Można to również wykorzystać do rzeczywistych tłumaczeń komunikatów o wyjątkach.


Pytania ::

  • Czy to oznacza language specificwdrożenia? na przykład jeśli używam e.getLocalizedMessage()na przykład mojej aplikacji English- błąd zostanie wyrzucony English, jeśli użyję mojej aplikacji Spanish- wtedy błąd zostanie wrzuconySpanish

  • Potrzebuję jasnego wyjaśnienia, gdzie i kiedy mogę użyć tych metod do mojego zastosowania

Devrath
źródło
1
Tak, oznacza to implementacje specyficzne dla lokalizacji (języka, kultury). Co jest nie tak z oficjalną dokumentacją ?
domyślny język

Odpowiedzi:

72

Jak wszyscy wspomnieli powyżej -

W moim rozumieniu getMessage()zwraca nazwę wyjątku. getLocalizedMessage()zwraca nazwę wyjątku w lokalnym języku użytkownika (chiński, japoński itp.). Aby to zadziałało, klasa, do której dzwonisz, getLocalizedMessage()musi przesłonić getLocalizedMessage()metodę. Jeśli tak nie jest, wywoływana jest metoda jednej z jego superklas, która domyślnie zwraca tylko wynik funkcji getMessage.

Oprócz tego chciałbym umieścić fragment kodu wyjaśniający, jak go używać.

Jak tego użyć

Java nie robi nic magicznego, ale ułatwia nam życie. Aby getLocalizedMessage()skutecznie używać , musimy nadpisać domyślne zachowanie.

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 służy do lokalizacji.

W tym przykładzie w loc/exc/testścieżce należy umieścić pliki właściwości specyficzne dla języka . Na przykład:

message_fr.properties (zawiera klucz i wartość):

key1=this is key one in France

message.properties (zawierający klucz i wartość):

key1=this is key one in English

Teraz załóżmy, że nasza klasa generatora wyjątków jest podobna do

public class ExceptionGenerator {

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

a główna klasa to:

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

Domyślnie zwraca wartość klucza „English”, jeśli jest wykonywana w środowisku „English”. Jeśli ustawisz lokalny na Francję, otrzymasz wynik z pliku message_fr.

Kiedy go używać

Jeśli Twoja aplikacja musi obsługiwać l10n / i18n, musisz jej użyć. Jednak większość aplikacji nie musi tego robić, ponieważ większość komunikatów o błędach nie jest przeznaczona dla klienta końcowego, ale dla inżyniera wsparcia / inżyniera programisty.

dgm
źródło
6
„Zgodnie z moim zrozumieniem getMessage () zwraca nazwę wyjątku”. To jest po prostu złe. Nazwę wyjątku można znaleźć z e.getClass().getSimpleName(). new NullPointerException().getMessage()zwraca „null”, a nie „NullPointerException”.
Philip Whitehouse
1
Jednak pułapka polega na tym, że metoda w rzeczywistości nie przyjmuje ustawień regionalnych, więc nie zawsze jest możliwe uzyskanie ustawień regionalnych użytkownika. W szczególności sposób, w jaki wyjątek w tej odpowiedzi został zaimplementowany, umożliwi poprawną lokalizację wyjątku tylko dla aplikacji z interfejsem graficznym. W przypadku aplikacji po stronie serwera domyślne ustawienia regionalne maszyny JVM nie są takie same, jak ustawienia użytkownika, dlatego najlepszą zasadą jest nigdy nie wywoływać ResourceBundle.getBundle (String) i zawsze podawać rzeczywiste ustawienia regionalne użytkownika. (Na przykład w przypadku aplikacji internetowych zwykle otrzymujesz informacje o ustawieniach regionalnych użytkownika w nagłówku).
Trejkaz
6

To naprawdę zaskakujące - sprawdź kod openJDK 7 klasy Throwable.java .

Realizacja getLocalizedMessageis -

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

A wdrożenie getMessagejest -

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

I

130     private String detailMessage;

Nie ma zmiany we wdrażaniu obu metod, ale dokumentacja.

Subhrajyoti Majumder
źródło
15
Dokumentacja jasno mówi: „Podklasy mogą przesłonić tę metodę w celu wygenerowania komunikatu specyficznego dla ustawień regionalnych. W przypadku podklas, które nie zastępują tej metody, domyślna implementacja zwraca ten sam wynik, co getMessage ()”.
fool4jesus
2

Nie. zdecydowanie nie oznacza to implementacji specyficznych dla języka. Oznacza to implementacje, które wykorzystują mechanizm internacjonalizacji (aka i18n). zobacz tę stronę, aby uzyskać więcej informacji o tym, jakie są pakiety zasobów i jak z nich korzystać.

Istota jest taka, że ​​umieszczasz dowolny tekst w plikach zasobów, których masz wiele (po jednym na język / język / itp.), a Twój kod używa mechanizmu do wyszukiwania tekstu w odpowiednim pliku zasobów (łącze, które podałem, prowadzi do szczegółów ).

kiedy i gdzie zostanie to użyte, zależy wyłącznie od Ciebie. Zwykle martwisz się tym tylko wtedy, gdy chcesz przedstawić wyjątek nietechnicznemu użytkownikowi, który może nie znać dobrze angielskiego. więc na przykład, jeśli piszesz tylko do dziennika (który zwykle czytają tylko użytkownicy techniczni, a więc nie jest powszechnym celem i18n), zrobiłbyś:

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

ale jeśli zamierzasz wyświetlić komunikat o wyjątku na ekranie (na przykład jako mały dialog), możesz chcieć wyświetlić komunikat w lokalnym języku:

try {
   somethingDangerous();
} catch (Exception e) {
   JOptionPane.showMessageDialog(frame,
    e.getLocalizedMessage(),
    "Error",  <---- also best be taken from i18n
    JOptionPane.ERROR_MESSAGE);
}
radai
źródło
2
public String  getMessage() 

Zwraca szczegółowy komunikat o tym obiekcie do rzucania.

public String getLocalizedMessage() 

Tworzy zlokalizowany opis tego przedmiotu miotanego. Podklasy mogą przesłonić tę metodę w celu wygenerowania komunikatu specyficznego dla ustawień regionalnych. W przypadku podklas, które nie zastępują tej metody, domyślna implementacja zwraca ten sam wynik, co getMessage().

W twoim przypadku e jest niczym innym jak przedmiotem wyjątku ...

getLocalizedMessage() Musisz nadpisać i podać swój własny komunikat, tj. znaczenie zlokalizowanej wiadomości.

Na przykład ... jeśli istnieje wyjątek wskaźnika zerowego ...

Po wydrukowaniu e wyświetli wartość null

e.getMessage() ---> NullPointerException
Umer Kiani
źródło
2

To właśnie ma do powiedzenia klasa Throwable.java. Może to komuś pomoże:

/**
 * 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();
}
sivi
źródło
-2

Zgodnie z moim zrozumieniem, getMessage zwraca nazwę wyjątku. getLocalizedMessage zwraca nazwę wyjątku w lokalnym języku użytkownika (chiński, japoński itp.). Aby to zadziałało, klasa, do której wywołujesz getLocalizedMessage, musi przesłonić metodę getLocalizedMessage. Jeśli tak nie jest, wywoływana jest metoda jednej z jego superklas, która domyślnie zwraca tylko wynik funkcji getMessage.

W większości przypadków wynik będzie taki sam, ale w niektórych przypadkach zwróci nazwę wyjątku w języku regionu, w którym program jest uruchamiany.

Czy to oznacza implementacje specyficzne dla języka? na przykład jeśli używam e.getLocalizedMessage () na przykład moja aplikacja w języku angielskim - błąd zostanie wyrzucony w języku angielskim, jeśli używam mojej aplikacji w języku hiszpańskim - błąd zostanie wyrzucony w języku hiszpańskim

public String 
getMessage() 

Returns the detail message string of this throwable.





public String 
getLocalizedMessage() 

Tworzy zlokalizowany opis tego przedmiotu miotanego. Podklasy mogą przesłonić tę metodę w celu wygenerowania komunikatu specyficznego dla ustawień regionalnych. W przypadku podklas, które nie zastępują tej metody, domyślna implementacja zwraca ten sam wynik, co metoda getMessage ().

W twoim przypadku e jest niczym innym jak przedmiotem wyjątku ...

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

Na przykład ... jeśli istnieje wyjątek wskaźnika zerowego ...

Po wydrukowaniu e wyświetli wartość null

e.getMessage() ---> NullPointerException 

Czytaj więcej...

Deepanshu J bedi
źródło
-2

Według mojego zrozumienia getMessage zwraca nazwę wyjątku.

getLocalizedMessage zwraca nazwę wyjątku w lokalnym języku użytkownika (chiński, japoński itp.).

Aby to zadziałało, klasa, do której dzwonisz, getLocalizedMessagemusiała zastąpićgetLocalizedMessage metodę.

Jeśli tak nie jest, wywoływana jest metoda jednej z jego superklas, która domyślnie zwraca tylko wynik getMessage.

rahul
źródło