Il set di caratteri, la codifica e la terminazione sono tre cose diverse. Ovviamente, una codifica è progettata per un set di caratteri specifico ma un set di caratteri può essere codificato in più modi. E, spesso, un terminatore (se usato) è un carattere codificato, ma con UTF-8 modificato, questo non è il caso.
Java utilizza il set di caratteri Unicode. Per i tipi stringa e char, utilizza la codifica UTF-16. Il tipo di stringa viene contato; Non usa un terminatore.
In C, le stringhe terminate sono comuni, nonché le codifiche a singolo byte di vari set di caratteri. I compilatori C e C++ terminano le stringhe letterali con il carattere NUL. Nella codifica del set di caratteri di destinazione del compilatore, questo è uno o due 0x00 byte. Quasi tutti i set di caratteri comuni e le loro codifiche hanno la stessa rappresentazione in byte per i caratteri ASCII senza controllo . Questo è vero per la codifica UTF-8 del set di caratteri Unicode. (Ma, nota che non è vero per i caratteri al di fuori del sottoinsieme limitato.)
I progettisti JNI hanno scelto di utilizzare questa "interoperabilità" limitata tra le stringhe C. Molte funzioni JNI accettano con terminazione 0x00 modificata stringhe UTF-8. Sono compatibili con ciò che un compilatore C produce da una stringa letterale nel codice sorgente, sempre a condizione che i caratteri siano limitati ai caratteri ASCII senza controllo. Questo copre il caso d'uso della scrittura del pacchetto Java & classe, metodo e stringhe di campo in JNI. (Bene, quasi: Java consente qualsiasi simbolo di valuta Unicode in un identificatore.)
Quindi, è possibile passare i valori letterali di stringa C alle funzioni JNI in uno stile WYSIWYG. Non c'è bisogno di aggiungere un terminatore, il compilatore lo fa. Il compilatore C codifica caratteri extra '\ 0' come 0x00 in modo da non causare alcun danno ma non è necessario.
Ci sono un paio di modifiche dalla codifica UTF-8 standard. Uno è quello di consentire alle funzioni C che prevedono un terminatore 0x00 di "gestire" le stringhe UTF-8 modificate, il carattere NUL (U + 00000) è codificato per evitare 0x00, che sarebbe lo standard. Ciò consente di modificare le stringhe UTF-8 modificate in un buffer con un terminatore 0x00 oltre i byte della stringa codificata originale. L'altra modifica è un po 'esoterica ma entrambe le modifiche rendono incompatibile una stringa UTF-8 modificata con una funzione UTF-8 strettamente conforme.
Non hai chiesto, ma c'è un altro uso di stringhe UTF-8 terminate 0x00 in JNI. È con le funzioni GetStringUTFChars
e NewStringUTF
. (La documentazione JNI in realtà non dice che GetStringUTFChars
restituisce una stringa terminata 0x00 ma non sono note implementazioni JVM che non lo siano. Controlla la documentazione del tuo implementatore JVM o il codice sorgente.) Queste funzioni sono progettate sulla stessa base di "interoperabilità". Tuttavia, i casi d'uso sono diversi, rendendoli pericolosi. Sono generalmente utilizzati per passare stringhe Java tra funzioni C. Le funzioni C, in generale, non avrebbero idea di cosa sia UTF-8 modificato, o forse nemmeno di cosa siano UTF-8 o Unicode. È molto più diretto utilizzare le classi Java String
e Charset
per convertire in e da set di caratteri e codifiche per le quali sono state progettate le funzioni C. Spesso, si tratta di un'impostazione di sistema, di un'impostazione utente, di un'impostazione dell'applicazione o di un'impostazione di thread che determina quale funzione C sta utilizzando. La classe Java String
tenta di conformarsi a tali impostazioni quando non viene fornita una codifica specifica per una conversione. Ma, in molti casi, la codifica desiderata è fissa e può essere specificata con intento chiaro.
Che cosa è successo quando hai provato, ha funzionato o no? – mah
@mah Le domande richiedono "dovrebbe" non "potrebbe". È sulla correttezza tecnica non ["programmazione per coincidenza".] (Http://pragprog.com/the-pragmatic-programmer/extracts/coincidence) Naturalmente funziona ma non è corretto. –