2012-11-02 10 views
5

W kodzie źródłowym com.sun.org.apache.xerces.internal.impl.XMLScanner na linii 183 i 186automatycznie internowania od napisowych

183 protected final static String fVersionSymbol = "version".intern(); 

186 protected final static String fEncodingSymbol = "encoding".intern(); 

Dlaczego „wersja” i „kodowanie” są wyraźnie internowany za pomocą intern(), gdy są literały ciągów znaków i zostaną automatycznie internowane?

+2

+1 Dobre pytanie! Efekt jest taki sam, jednak kod bajtowy generowany zi bez i jest inny. Sądzę, że nigdy się nie dowiemy, chyba że zapytamy bezpośrednio autorów, więc nie można na nie odpowiedzieć. Powiedziałbym, że była to przedwczesna optymalizacja. – OscarRyz

Odpowiedz

6

Śledziłem zmianę do revision 318617 in the Apache Xerces SVN Repository (jest to projekt, w którym pierwotnie opracowano analizator składni XML, jak sugeruje nazwa pakietu).

Istotna część wiadomości popełnienia jest:

Próbując poprawić wykorzystanie tabel symboli. Wiele predefiniowanych ciągów znaków jest dodawanych do tabel symboli za każdym razem, gdy parser jest resetowany. Dla małych dokumentów, byłby to znaczny koszt. Teraz, ponieważ wywołujemy String # intern dla Ciągów znaków w tabeli symboli, wystarczy użyć String # intern dla wstępnie zdefiniowanych symboli . Tę czynność należy wykonać tylko raz.

Jak już wspomniano, .intern() nie powinno być konieczne (i nie powinno mieć widocznego efektu) na zgodnej implementacji JVM.

Domyślam się, że

  • albo autor nie był świadomy faktu, że literały łańcuchowe zawsze będzie internowany
  • lub była to świadoma decyzja, aby zapobiec przed realizacją wadliwie JVM

W drugim przypadku spodziewałbym się jednak uwagi w komentarzu lub w komunikacie z komentarzem.

Jednym efektem ubocznym tego .intern() połączenia jest to, że nie są już inicjalizatory constant expressions i pola nie będą wstawiane przez inne klasy odwołującego them.That zagwarantuje, że klasa XMLScanner jest załadowany i jego pole czytać. Nie sądzę jednak, żeby miało to znaczenie.

+1

z komunikatu zatwierdzenia: '...Wiele predefiniowanych ciągów znaków jest dodawanych do tabel symboli za każdym razem, gdy parser jest resetowany ... Teraz, odkąd wywoływamy String # intern dla Ciągów w tablicy symboli ... wystarcza użycie String # intern dla tych predefiniowanych symboli. To musi być wykonane tylko raz. "- Jest oczywiste, że autor nie chce dodawać PREDEFINED String SYMBOLS z kodu ponownie do tabeli symboli, gdy parser jest resetowany. Najprawdopodobniej autor nie jest świadomy faktu, że literały łańcuchowe są automatycznie internowane. –

4

nie wierzę, istnieje jakikolwiek dobry powód, dla określonego powodu: Literówki są zawsze automatycznie internowany, jako defined by the String class:

Wszystkie ciągami tekstowymi i ciąg wycenione wyrażenia stałe są internowany. Literały łańcuchowe są zdefiniowane w sekcji 3.10.5 specyfikacji języka Java ™.

+1

, więc czy jest to przykład złego kodowania? –

+2

@aLearner: Przypuszczam. Prawdopodobnie nie powiedziałbym tego tak mocno, ale przynajmniej jeśli istnieje ku temu dobry powód (w co wątpię), oczekiwałbym komentarza wyjaśniającego, co to jest. –

Powiązane problemy