Java: Pourquoi suis-je obligé d'initialiser une variable locale primitive?

public class Foo {
    public static void main(String[] args) {
        float f;
        System.out.println(f);
    }
}

L'instruction print provoque l'erreur de compilation suivante,

La variable locale f n'a peut-être pas été initialisée

Si les primitives en Java ont déjà une valeur par défaut (float = 0.0 f), Pourquoi dois-je en définir une?


Modifier:

Donc, cela fonctionne

public class Foo {
    float f;
    public static void main(String[] args) {
        System.out.println(new Foo().f);
    }
}

Merci à tous!

23
demandé sur user1329572 2012-06-23 03:40:42

5 réponses

Parce que c'est une variable locale. C'est pourquoi rien ne lui est assigné:

Les variables locales sont légèrement différentes; le compilateur n'attribue jamais valeur par défaut à une variable locale non initialisée. Si vous ne pouvez pas initialisez votre variable locale où elle est déclarée, assurez - vous de affecter une valeur avant de tenter de l'utiliser. L'accès à une une variable locale non initialisée entraînera une erreur de compilation.

Edit: Pourquoi Java soulève cette compilation d'erreur ? Si l'on regarde l'IdentifierExpression.java fichier de classe, nous allons trouver ce bloc :

...
if (field.isLocal()) {
            LocalMember local = (LocalMember)field;
            if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) {
                env.error(where, "invalid.uplevel", id);
            }
            if (!vset.testVar(local.number)) {
                env.error(where, "var.not.initialized", id);
                vset.addVar(local.number);
            }
            local.readcount++;
        }
...

Comme indiqué (if (!vset.testVar(local.number)) {), le JDK vérifie (avec testVar) si la variable est assignée (Vset's code source où l'on peut trouver testVar code). Si ce n'est pas le cas, il déclenche l'erreur var.not.initialized à partir d'un fichier de propriétés :

...
javac.err.var.not.initialized=\
    Variable {0} may not have been initialized.
...

Source

44
répondu Zakaria 2016-05-04 21:05:45

En fait, le compilateur n'affecte pas une valeur par défaut à votre float f, car dans ce cas il s'agit d'une variable locale - et non d'un champ:

Les variables locales sont légèrement différentes; le compilateur n'attribue jamais de valeur par défaut à une variable locale non initialisée. Si vous ne pouvez pas initialiser votre variable locale où elle est déclarée, assurez-vous de lui attribuer une valeur avant de tenter de l'utiliser. L'accès à une variable locale non initialisée entraînera une compilation erreur.

14
répondu sarnold 2012-06-22 23:43:44

Les champs de classe (non - final de toute façon) sont initialisés aux valeurs par défaut. Les variables locales ne le sont pas.

, Il n'est pas toujours nécessaire d'assigner une valeur lorsqu'un champ est déclaré. Les champs déclarés mais non initialisés seront définis par défaut par le compilateur.

Donc un champ (non - final) comme f dans

class C {
  float f;
}

Sera initialisé à 0f, mais la variable locale f dans

void myMethod() {
  float f;
}

Ne sera pas.

Les variables locales sont traitées différemment des champs par la langue. Les variables locales ont une durée de vie bien étendue, donc toute utilisation avant l'initialisation est probablement une erreur. Les champs ne le font pas, l'initialisation par défaut est souvent pratique.

6
répondu Mike Samuel 2012-06-22 23:43:33

En Fait les variables locales sont stockées dans la pile.Par conséquent il y a une chance de prendre n'importe quelle valeur ancienne présent pour le local variable.It est un grand défi pour des raisons de sécurité..Par conséquent, java dit que vous devez initialiser un varible local avant utilisation.

2
répondu ram 2013-07-04 07:35:44

Salut Les gars solution est simple. les valeurs stockées sur la mémoire du tas sont initialisées par le type de données basé sur le compilateur, mais les variables locales sont stockées sur la mémoire de la pile, nous devons donc l'initialiser explicitement.

1
répondu user3728743 2015-02-19 07:22:22