2009-08-14 6 views
0

Je faisais un tutoriel Junit et je suis tombé sur cette fonction de normalisation qui était en train d'être testée. Il a été défini comme ceci:Comment fonctionne cette fonction de normalisation?

public static String normalizeWord(String word) { 
     try { 
      int i; 
      Class<?> normalizerClass = Class.forName("java.text.Normalizer"); 
      Class<?> normalizerFormClass = null; 
      Class<?>[] nestedClasses = normalizerClass.getDeclaredClasses(); 
      for (i = 0; i < nestedClasses.length; i++) { 
       Class<?> nestedClass = nestedClasses[i]; 
       if (nestedClass.getName().equals("java.text.Normalizer$Form")) { 
        normalizerFormClass = nestedClass; 
       } 
      } 
      assert normalizerFormClass.isEnum(); 
      Method methodNormalize = normalizerClass.getDeclaredMethod(
                  "normalize", 
                  CharSequence.class, 
                  normalizerFormClass); 
      Object nfcNormalization = null; 
      Object[] constants = normalizerFormClass.getEnumConstants(); 
      for (i = 0; i < constants.length; i++) { 
       Object constant = constants[i]; 
       if (constant.toString().equals("NFC")) { 
        nfcNormalization = constant; 
       } 
      } 
      return (String) methodNormalize.invoke(null, word, nfcNormalization); 
     } catch (Exception ex) { 
      return null; 
     } 
    } 

Comment fonctionne cette fonction? Que fait-il réellement?

+3

Cela appartient à TheDailyWTF. –

Répondre

5

Il fait la même chose que:

import java.text.Normalizer; 

try { 
    return Normalizer.normalize(word, Normalizer.Form.NFC); 
} catch (Exception ex) { 
    return null; 
} 

Sauf que toutes les opérations sont effectuées par réflexion.

+0

Et il devrait être écrit de cette façon, sauf si vous avez vraiment besoin de compiler (par opposition à simplement courir) sur pré-Java6. Si vous attrapez toutes les exceptions (et peut-être quelques erreurs liées au chargement de classe), ce code se dégradera même avec élégance sur JDK5 où la classe Normalizer n'est pas présente. Cependant, vous devrez compiler sur Java6. (Avec la version réfléchissante, vous pouvez aussi compiler sur des Java plus anciens, bien qu'on puisse prétendre que vous ne compilez rien, avec tout le reflet qui s'y trouve). – Thilo

3

Il utilise la réflexion pour appeler

java.text.Normalizer.normalize(word, java.text.Normalizer.Form.NFC); 

On peut supposer que pour lui permettre de fonctionner sur les versions Java avant 1.6 qui ne disposent pas de cette classe.

+0

@Ben: Vous avez probablement raison: http://stackoverflow.com/questions/1277270 –

2

Cette fonction offre des services concernant la normalisation des chaînes pour Unicode. En Unicode, vous pouvez représenter la même chose de plusieurs façons. Par exemple, vous avez un personnage avec accent. Vous pouvez le représenter joint, en utilisant un seul caractère Unicode, ou décomposé (la lettre originale, sans accents, puis le modificateur - l'accent).

La classe est disponible en Java 6. Pour Java 5, il existe une classe propriétaire SUN.

Voir classe info.olteanu.utils.TextNormalizer dans le projet Phramer (http://sourceforge.net/projects/phramer/, www.phramer.org) pour un moyen d'obtenir un normalisateur à la fois en Java 5 (JDK SUN) et en Java 6, sans aucun problème de compilation (le code compilera dans un version> = 5 et le code s'exécutera dans les deux JVM, bien que SUN ait abandonné la classe propriétaire Java 5).

Questions connexes