3 votes

La modification des valeurs des chaînes booléennes par réflexion ne fonctionne pas

J'ai fait des expériences avec la réflexion Java et les chaînes de caractères en ligne et je suis arrivé à un résultat que je trouve déroutant.

import java.lang.reflect.Field;

public class HappyDebugging {

    public static void main(String[] args) throws Exception {
        defineTrueFalse();

        System.out.println("true is " + true); // why is it "true is true"?
        System.out.println("false is " + false);
        System.out.println(true);
        System.out.println(false);
        System.out.println("true");
        System.out.println("false");
        System.out.println("true is " + Boolean.valueOf(true));
        System.out.println("false is " + Boolean.valueOf(false));
        System.out.println("true is " + Boolean.valueOf("true"));
        System.out.println("false is " + Boolean.valueOf("false"));
    }

    static void defineTrueFalse() throws Exception{
        Field field = String.class.getDeclaredField("value");
        field.setAccessible(true);
        field.set("true", new char[] {'f', 'a', 'l', 's', 'e'});
        field.set("false", new char[] {'t', 'r', 'u', 'e'});

        field = String.class.getDeclaredField("offset");
        field.setAccessible(true);
        field.setInt("true", 0);
        field.setInt("false", 0);

        field = String.class.getDeclaredField("count");
        field.setAccessible(true);
        field.setInt("true", 5);
        field.setInt("false", 4);
    }
}

Pourquoi les deux premières lignes de la sortie sont-elles

true is true
false is false

Je m'attends à ce qu'ils soient

true is false
false is true

Veuillez noter que le résultat varie selon les plateformes.

17voto

Gil Points 353

Cela semble fonctionner....

String.valueOf(BooleanValue)

6voto

ruakh Points 68789

Dans mon compilateur, ces deux lignes sont compilées pour utiliser les chaînes de caractères réelles "true is true" et "false is false" (c'est-à-dire qu'il n'y a pas de concaténation au moment de l'exécution), de sorte que votre mal réflexif arrive trop tard. Vous dites que le résultat dépend de la plateforme, donc je suppose que certains compilateurs ne doivent pas effectuer cette optimisation.

4voto

Sunil Kumar Sahoo Points 21032

defineTrueFalse n'a pas d'effet, de sorte que "true is " + true est traité comme "true is " + Boolean.toString(true) C'est pourquoi le résultat est le suivant true is true

3voto

Hons Points 1311

La réponse est simple. Ces deux lignes

 System.out.println("true is " + true);
 System.out.println("false is " + false);

faire ce qui suit. 1. la valeur simple de type booléen "true" est convertie en String, ce qui donne la chaîne "true". Il en va de même pour "false", et c'est tout

2voto

Michael Borgwardt Points 181658

Parce que vous manipulez le contenu de String literals internés (d'une manière qui condamnera votre âme à des souffrances éternelles dans le neuvième cercle de l'enfer), mais vos deux premières lignes concatènent des boolean literals, pas des String literals. Rien dans defineTrueFalse() n'a aucun effet sur les valeurs booléennes true et false (par opposition aux chaînes de caractères "true" et "false" ).

Veuillez noter que le résultat varie selon les plateformes.

Mais pas pour les deux premières lignes, je le parierais. Pour les choses liées aux chaînes de caractères, c'est possible, puisque le comportement dépend de l'interprétation des littéraux de chaînes de caractères, ce qui, je pense, n'est pas garanti par la spécification (donc, neuvième cercle de l'enfer).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X