2011-11-10 9 views
6

Il seguente programma Java semplice sembra visualizzare la stringa Ciao Mondo attraverso la dichiarazione System.out.println("Hello World"); ma non è così. Semplicemente sostituisce questo con un'altra stringa che è in questo caso, Good Day !! e lo visualizza sulla console. La stringa Hello World non viene visualizzata affatto. Diamo un'occhiata al seguente frammento di codice semplice in Java.Un codice Java semplice che funziona bene ma le funzioni in un modo che è un po 'difficile da seguire

package goodday; 

import java.lang.reflect.Field; 

final public class Main 
{ 
    public static void main(String[] args) 
    {   
     System.out.println("Hello World"); 
    } 

    static 
    { 
     try 
     { 
      Field value = String.class.getDeclaredField("value"); 
      value.setAccessible(true); 
      value.set("Hello World", value.get("Good Day !!")); 
     } 
     catch (Exception e) 
     { 
      throw new AssertionError(e); 
     } 
    } 
} 

Solo una domanda su questo codice qui. Funziona esattamente come previsto ma non posso ridurre la lunghezza della corda Good Day !!. Se viene fatto un tentativo per farlo, provoca un java.lang.ArrayIndexOutOfBoudsException. Se la lunghezza viene aumentata, il programma funziona bene ma il resto dei caratteri nella stringa di visualizzazione viene troncato significa che la lunghezza di entrambe le stringhe dovrebbe essere in qualche modo la stessa. Perché? Questa è la cosa che non ho potuto capire.

+3

Naturalmente ti rendi conto che non dovresti mai farlo mai in codice reale? –

+2

Conosco Java da molto tempo, ma non ho mai visto nulla di simile prima, davvero una bella domanda: D –

risposta

7

Il campo value è un char[] che memorizza internamente l'array di caratteri utilizzato dalla stringa come backing store. Altri campi indicano l'offset iniziale nell'array di caratteri e la lunghezza della stringa. (Quindi, per creare una sottostringa, crea semplicemente un nuovo oggetto String che si riferisce allo stesso char[] ma con un offset iniziale e una lunghezza diversi.)

Se si modificano anche questi campi, è possibile fare praticamente tutto ciò che si desidera con la corda. Esempio:

import java.lang.reflect.Field; 

public class Test 
{ 
    // Obviously in real code you wouldn't use Exception like this... 
    // Although hacking string values with reflection is worse, of course. 
    public static void main(String[] args) throws Exception 
    {   
     System.out.println("Hello World"); 
     replaceHelloWorld("Goodbye!"); 
     System.out.println("Hello World"); 
     replaceHelloWorld("Hello again!"); 
     System.out.println("Hello World"); 
    } 

    static void replaceHelloWorld(String text) throws Exception 
    { 
     // Note: would probably want to do hash as well... 
     copyField(text, "Hello World", "value"); 
     copyField(text, "Hello World", "offset"); 
     copyField(text, "Hello World", "count"); 
    } 

    static void copyField(String source, String target, String name) 
     throws Exception 
    { 
     Field field = String.class.getDeclaredField(name); 
     field.setAccessible(true); 
     field.set(target, field.get(source)); 
    } 
} 
+2

Dovresti sapere meglio di incoraggiare questo ... :-) –

Problemi correlati