2014-04-26 7 views
14

Ich muss ein String zu Byte-Array mit UTF-8-Codierung codieren. Ich benutze Google Guava, hat Charsets-Klasse bereits definieren Charset-Instanz für UTF-8-Codierung. Ich habe 2 Möglichkeiten zu tun:Java String.getBytes (charsetName) vs String.getBytes (Charset-Objekt)

  1. String.getBytes (charsetName)

    try {   
        byte[] bytes = my_input.getBytes ("UTF-8"); 
    } catch (UnsupportedEncodingException ex) { 
    
    } 
    
  2. String.getBytes (Charset Objekt)

    // Charsets.UTF_8 is an instance of Charset  
    
    byte[] bytes = my_input.getBytes (Charsets.UTF_8); 
    

Meine Frage ist, welche ein Ich sollte verwenden? Sie geben das gleiche Ergebnis zurück. Für Weg 2 - ich muss nicht versuchen/fangen! Ich schaue mir den Java-Quellcode an und sehe, dass 1 und 2 anders implementiert werden.

Wer hat irgendwelche Ideen?

+0

Erhalten Sie gleichwertige Ergebnisse von beiden? Wenn ja, würde ich den letzteren Fall bevorzugen. Wenn nicht, müssen Sie entscheiden, was Sie für richtig halten. – merlin2011

+0

Ja, sie geben das gleiche Ergebnis zurück. Aber mein Anliegen ist, warum sie anders umgesetzt werden? Warum wird Weg Nr. 2 intern nicht aufgerufen? – Loc

+0

@Loc Was lässt Sie denken, dass der erstere das letztere nicht intern nennt?(oder dass sie beide nicht eine andere gemeinsame interne Methode nennen würden?) http://www.docjar.com/html/api/java/lang/String.java.html Zeilen 951 - 980 –

Antwort

2

Da sie dasselbe Ergebnis zurückgeben, sollten Sie Methode 2 verwenden, da es im Allgemeinen sicherer und effizienter ist, die Bibliothek nicht zu bitten, eine vom Benutzer bereitgestellte Zeichenfolge zu analysieren und möglicherweise zu unterbrechen. Wenn Sie den Try-Catch vermeiden, wird auch Ihr eigener Code sauberer.

Die Charsets.UTF_8 kann leichter zur Kompilierungszeit überprüft werden, was wahrscheinlich der Grund ist, warum Sie keine try-catch benötigen.

8

Die erste API ist für Situationen, in denen Sie den Zeichensatz zum Zeitpunkt der Kompilierung nicht kennen; der zweite ist für Situationen, in denen du es tust. Da es scheint, dass Ihr Code UTF-8 muss speziell, sollten Sie die zweite API bevorzugen:

byte[] bytes = my_input.getBytes (Charsets.UTF_8); // <<== UTF-8 is known at compile time 

Die erste API ist für Situationen, in denen die charset von außerhalb Ihr Programm kommt - zum Beispiel aus der Konfigurationsdatei von Benutzereingaben, als Teil einer Client-Anfrage an den Server und so weiter. Aus diesem Grund wird eine geprüfte Ausnahme ausgelöst - für Situationen, in denen der in der Konfiguration oder auf andere Weise angegebene Zeichensatz nicht verfügbar ist.

2

Wenn Sie bereits den Zeichensatz haben, verwenden Sie die zweite Version, da sie weniger fehleranfällig ist.

13

Wenn Sie ein String-Literal (z. B. "UTF-8") verwenden ... sollten Sie nicht. Verwenden Sie stattdessen die zweite Version und geben Sie den konstanten Wert von StandardCharsets an (in diesem Fall StandardCharsets.UTF_8). Die erste Version wird verwendet, wenn der Zeichensatz dynamisch ist. Dies wird der Fall sein, wenn Sie nicht wissen, was der Zeichensatz zum Zeitpunkt der Kompilierung ist; Es wird von einem Endbenutzer bereitgestellt, aus einer Konfigurationsdatei oder Systemeigenschaft usw. gelesen.

Intern rufen beide Methoden eine Version von StringCoding.encode() auf. Die erste Version von encode() sucht einfach zuerst die Charset mit dem angegebenen Namen und wirft eine Ausnahme, wenn dieser Zeichensatz unbekannt/nicht verfügbar ist.

+0

Nein. Intern rufen sie StringCoding.encode() auf, aber es gibt zwei Versionen von StringCoding.encode(). Der Weg 1 Aufruf dieser Methode mit dem ersten Parameter ist charsetName, way2 Aufruf dieser Methode mit dem ersten Parameter ist Charset-Instanz. 2 Versionen von StringCoding.encode() sind unterschiedlich implementiert. Ich weiß nicht warum. – Loc

+0

Tut mir leid, ich werde bearbeiten, um zu klären - das Nachschlagen geschieht in 'encode()' –