J'ai quelques cas où je me demande. Tout d'abord, si vous n'avez pas de constructeur: lorsque je fais Et si j'ai cette situation: p> quoi arrive quand j'appelle Qu'en est-il de cette version: p> nouveaux nocons () code>, le constructeur par défaut est appelé. Qu'est-ce que ça fait exactement? Est-ce qu'il définit x code> sur 0 ou cela se produit ailleurs? P> nouveau nocons2 () code>? Le constructeur par défaut code> est-il appelé NOCONS code>, puis constructeur de nocons2 code>? Est-ce qu'ils définissent chacun les champs respectifs x code> et y code> sur 0? P> class Cons { int x; public Cons() {} }
class NoCons2 extends Cons { int y; }
4 Réponses :
Lorsqu'une classe Java n'a pas de constructeur défini explicitement un constructeur de défaut de no-args public est ajouté, de sorte que:
new NoCons2();
Cletus a répondu au plus grand des questions. La réponse à l'autre est que les variables de membre en Java sont initialisées à 0, null ou false (selon le type). P>
Vous voulez vous référer au Spécification de la langue Java Section 12.5 Création de nouvelles instances de classe pour obtenir les règles officielles de la création d'objets. La section correspondante est la suivante:
juste avant la référence à l'objet nouvellement créé est renvoyé comme résultat, le constructeur indiqué est traité pour initialiser le nouvel objet en utilisant la procédure suivante: p>
- Attribuez les arguments du constructeur aux variables de paramètres nouvellement créées pour cette invocation du constructeur. LI>
- Si ce constructeur commence par une invocation de constructeur explicite d'un autre constructeur dans la même classe (en utilisant ceci), puis évaluez les arguments et traitez de ce que l'invocation du constructeur utilise récursivement ces cinq étapes. Si cette invocation du constructeur se termine brusquement, cette procédure complète brusquement la même raison; Sinon, continuez avec l'étape 5. Li>
- Ce constructeur ne commence pas par une invocation de constructeur explicite d'un autre constructeur dans la même classe (en l'utilisant). Si ce constructeur est pour une classe autre que l'objet, ce constructeur commencera par une invocation explicite ou implicite d'un constructeur de superclasse (en utilisant Super). Évaluez les arguments et procédez à l'invocation du constructeur de superclasse à l'aide de ces mêmes cinq étapes. Si cette invocation du constructeur est terminée brusquement, cette procédure complète brusquement la même raison. Sinon, continuez avec l'étape 4. Li>
- Exécutez les initialisateurs d'instance et les initialisateurs de variable d'instance pour cette classe, attribuant les valeurs d'initialistes variables d'instance aux variables d'instance correspondantes, dans l'ordre de gauche à droite dans lequel ils apparaissent textuellement dans le code source de la classe. Si l'exécution de l'un de ces initialiseurs entraîne une exception, aucune autre initialistes n'est traitée et cette procédure complète brusquement la même exception. Sinon, passez à l'étape 5. (Dans certaines implémentations précoces, le compilateur a mal omis le code pour initialiser un champ si l'expression d'initialisateur de champ était une expression constante dont la valeur était égale à la valeur d'initialisation par défaut pour son type.) Li>
- Exécutez le reste du corps de ce constructeur. Si cette exécution complète brusquement, cette procédure complète brusquement la même raison. Sinon, cette procédure se termine normalement. Li> ol> BlockQuote>
Donc, dans vos exemples, lorsque aucun constructeur n'est fourni dans votre définition de classe, le par défaut est inséré pour vous. Lorsque vous écrivez P>
new NoCons2();
Voici essentiellement ce qui se passe quand « nouveau » est appelé:
Si vous ne fournissez pas de constructeur le compilateur effectue les opérations suivantes: p>
Ainsi, lorsque le constructeur de la classe après la « nouvelle » est appelée la première chose qu'il fait est appel « super () » qui appelle le constructeur parent. Cela arrive tout le chemin jusqu'à java.lang.Object. P>
Avant que le corps du constructeur est exécuté la machine virtuelle effectue les opérations suivantes: p>
Le code suivant montre tous ceci: p>
public class Main
{
private Main()
{
}
public static void main(final String[] args)
{
final Foo fooA;
final Foo fooB;
fooA = new Foo(7);
System.out.println("---------------------");
fooB = new Foo(42);
}
}
class Bar
{
protected int valueA = getValue("valueA", 1);
protected int valueB;
static
{
System.out.println("static block for Bar happens only one time");
}
{
System.out.println("instance block for Bar happens one time for each new Bar");
System.out.println("valueA = " + valueA);
System.out.println("valueB = " + valueB);
}
Bar()
{
super(); // compiler adds this - you would not type it in
System.out.println("running Bar()");
System.out.println("valueA = " + valueA);
System.out.println("valueB = " + valueB);
valueB = getValue("valueB", 2);
}
protected static int getValue(final String name, final int val)
{
System.out.println("setting " + name + " to " + val);
return (val);
}
}
class Foo
extends Bar
{
protected int valueC = getValue("valueC", 1);
protected int valueD;
static
{
System.out.println("static block for Foo happens only one time");
}
{
System.out.println("instance block for Foo happens one time for each new Foo");
System.out.println("valueC = " + valueC);
System.out.println("valueD = " + valueD);
}
Foo(final int val)
{
super(); // compiler adds this - you would not type it in
System.out.println("running Foo(int)");
System.out.println("valueC = " + valueC);
System.out.println("valueD = " + valueD);
valueD = getValue("valueD", val);
}
}