2010-06-29 8 views
3

J'ai une classe,aide avec des variables statiques en Java

class MyClass { 
    private int val; 
    public static final MyClass myObject = new MyClass(1); 
    MyClass(int a){ 
     val = a; 
    } 
    public int getVal(){ 
     return val; 
    } 
    public MyClass func1(){ 
     MyClass temp = myObject; 
     temp.val = 2; 
     return temp; 
    } 
    public static void main(String [] args){ 
     MyClass x = new MyClass(4); 
     System.out.println(myObject.getVal()); 
     x.func1(); 
     System.out.println(myObject.getVal()); 
    } 
} 

Il imprime:

1 
2 

je m'y attendais à imprimer:

1 
1 

Il semble y avoir un malentendu fondamental de ma part. Je m'attendais à ce que myObject étant une valeur final static ne peut pas être changé, et quand je fais MyClass temp = myObject, je crée un nouvel objet appelé temp de type MyClass et affectez la valeur de myObject à cet objet nouvellement créé. S'il vous plait corrigez moi si je me trompe. Il semble qu'il n'y a pas de nouvel objet créé et temp pointe simplement vers l'original myObject

EDIT: Merci pour les réponses! Je comprends maintenant que l'opérateur = ne fait jamais une copie de l'objet, il copie juste la référence. Ce dont j'ai besoin est de faire une copie de myObject et de le stocker dans temp. Quel serait le meilleur moyen d'y parvenir?

EDIT2: Un autre comportement étrange ou une caractéristique de Java?

I modifié le code légèrement

class MyClass { 
    private Integer val; 
    public static final MyClass myObject = new MyClass(1); 
    MyClass(int a){ 
     val = a; 
    } 
    public int getVal(){ 
     return val; 
    } 
    public MyClass func1(){ 
     MyClass temp = new MyClass(33); 
     temp.val = myObject.val; 
     temp.val = 2; 
     return temp; 
    } 
    public static void main(String [] args){ 
     MyClass x = new MyClass(4); 
     System.out.println(myObject.getVal()); 
     MyClass y = x.func1(); 
     System.out.println(x.getVal()); 
     System.out.println(y.getVal()); 
     System.out.println(myObject.getVal()); 
    } 
} 

sortie est

1 
4 
2 
1 

Par conséquent, lorsque je crée temp à l'aide new MyClass(33) puis définissez temp.val = 2, il est en fait une copie de val. En d'autres termes, temp.val ne pointe pas vers myObject.val. Pourquoi cela est-il ainsi?

+0

Je pense que vous essayez d'appliquer Singleton Pattern http://en.wikipedia.org/wiki/Singleton_pattern#Java BTW, votre question est déjà répond en plusieurs réponses ci-dessous. –

Répondre

7
MyClass temp = myObject; 

Ce ne crée pas une nouvelle instance, il vient d'assigner la référence de sorte que les points temporaires à la même instance que myObject.

Ainsi, votre déclaration:

créer un nouvel objet appelé température de de type MyClass

est incorrect, que vous n'êtes pas en train de créer un nouvel objet ici, simplement attribuer une référence d'objet .

EDIT Si votre objectif est de faire une copie de myObject et le retourner de func1(), alors vous pouvez le faire (par copie Je suppose que vous voulez dire copier la valeur et val, si vous voulez utiliser un autre valeur pour val alors vous pouvez régler ce code en conséquence):

public MyClass func1(){ 
    MyClass temp = new MyClass(myObject.getVal()); 
    return temp; 
} 
5

Le champ est final, ce qui signifie que vous ne pouvez pas réaffecter le champ. Votre var myObject, cependant, n'est pas immuable. Lorsque vous appelez func1() sur votre myObject, vous changez myObject.val à 2.

1

Je pense que vous avez un peu répondu à votre propre question. Vous avez raison de dire qu'il n'y a pas vraiment un nouvel objet créé par la ligne MyClass temp = myObject; temp est seulement une référence d'objet à votre instance statique de myClass.

Vous pouvez vérifier ceci en modifiant le code.

public MyClass func1(){ 
    MyClass temp = myObject; 
    System.out.println(myObject == temp);//print true 
    temp.val = 2; 
    return temp; 
} 
2

Vous obtenez une référence à une instance de l'objet MyClass et modifiez l'un de ses membres. Cette référence n'est pas immuable; Seul le champ nommé myObj est immuable.

1

En Java, l'opérateur = attribue des références, pas des objets comme en C++.

Un dernier champ ne peut être affecté qu'une seule fois. Cela ne signifie pas que les objets accessibles via un champ final ne peuvent pas être modifiés. En d'autres termes: Contrairement à const de C++, final ne protège que la référence, pas l'objet.

+0

Cela dépend de l'endroit où vous mettez le 'const' en C++ (ou C). –

0

Définition des modificateurs états finaux qui ne peut pas être changé la référence d'objet. Dans le premier extrait de code

public static final MyClass myObject = new MyClass(1); 

myObject est une référence finale qui pointe vers un objet avec val = 1. Toutefois, cela n'implique pas que le contenu de l'objet ne puisse pas être modifié. la fonction func1() obtient une référence sur l'objet avec la valeur 1 et change son val à 2. ce qui est parfaitement légal.

Pour le second extrait

public MyClass func1(){ 
    MyClass temp = new MyClass(33); 
    temp.val = myObject.val; 
    temp.val = 2; 
    return temp; 
} 
public static void main(String [] args){ 
    MyClass x = new MyClass(4);    //line A 
    System.out.println(myObject.getVal()); //returns 1 
    MyClass y = x.func1();     //line B 
    System.out.println(x.getVal());   //line C 
    System.out.println(y.getVal());   //line D 
    System.out.println(myObject.getVal()); 
} 

A la ligne A obj avec val 4 est créé.
A la ligne B, func1 est appelée, ce qui crée un nouvel objet en résumé avec val = 33 qui est alors changé en val = 1 puis val = 2.
À la ligne C, nous obtenons la sortie 4 de l'obj créé à la ligne A.
À la ligne D, nous obtenons la sortie 2 des changements que nous avons faits en utilisant la ligne B.
A la ligne E, nous obtenons la sortie 1 de l'objet final statique qui n'est pas modifié.