2012-11-26 6 views
-3

Disons par exemple que nous avons une classe Board avec de nombreux domaines (par exemple une classe assez complexe). Nous instancier un conseil comme ceci:références d'objets pointant vers le même objet

Board b = new Board(); 

Notez que pour des raisons de cet exemple, je ne pénètre pas dans tous les paramètres dans le constructeur, bien que dans un exemple réel, ceux-ci peuvent être nécessaires. Si nous devions instancier alors une nouvelle instance de conseil et Le mettre à être comme ceci:

Board c = b; 

Ce ne serait pas réellement créer un nouveau conseil d'administration. D'après ce que je sais, c et b pointent maintenant vers la même zone de mémoire, le même objet Board. Donc, si je devais changer quelque chose au sujet b, par exemple être incrémenter un champ entier, comme ceci:

b.count++;//Assume count is an integer field in the Board class. 

La valeur c.count doit être incrémentée aussi bien. Cependant, quand je le fais moi-même, ça ne marche pas. b.count est incrémenté, mais c.count ne l'est pas.
Quelqu'un peut-il m'expliquer pourquoi cela se produit? Cet effet est quelque chose que je veux arriver, donc tout conseil sur la façon de mettre en œuvre ce serait très utile (les exemples généraux sont bien).

+4

Pourriez-vous s'il vous plaît poster l'exemple reproduire –

+1

je _really_ aime voir l'exemple. –

+1

Comment chaque réponse a le même exemple ... Je commence à me demander si je ne peux pas voir le code dans la question OP. – dreamcrash

Répondre

2

Mauvais nouveau:

package cruft; 

/** 
* Board description here 
* @author Michael 
* @link 
* @since 11/26/12 6:46 PM 
*/ 
public class Board { 

    public int count; 

    public static void main(String[] args) { 
     Board b = new Board(); 
     Board c = b; 
     System.out.println("b before: " + b); 
     System.out.println("c before: " + c); 

     ++b.count; 

     System.out.println("b after : " + b); 
     System.out.println("c after : " + c); 
    } 

    @Override 
    public String toString() { 
     final StringBuilder sb = new StringBuilder(); 
     sb.append("Board"); 
     sb.append("{count=").append(count); 
     sb.append('}'); 
     return sb.toString(); 
    } 
} 
+1

Pour être technique, ça devrait être 'b.count ++;' –

+0

Non, ma façon fonctionne très bien. – duffymo

+0

Oui, mais c'est différent du code fourni par l'OP. –

1

Cela ne devrait pas se produire. Jetez un oeil à cet exemple.

public class Board { 

    public Integer count = 0; 

    public static void main(String[] args) 
    { 
     Board b = new Board(); 
     Board c = b; 

     c.count++; 

     System.out.println("b.count="+b.count); 
     System.out.println("c.count="+c.count); 
    } 

} 
0

Cela ne se produit pas dans un seul thread. Si vous faites cela c = b pour un deuxième thread, les règles de visibilité normales s'appliquent.

0

Tout d'abord, vous devriez essayer d'éviter d'utiliser public champs dans vos objets. Utilisez un champ private, puis utilisez une méthode getFieldName() et une méthode setFieldName(FieldType arg). De cette façon, vous avez plus de contrôle sur ce qui se passe, et vous pouvez ajouter du code si vous voulez que d'autres choses se produisent lorsqu'une certaine variable change.

Cela étant dit, vous devez avoir un bug dans votre code, parce que:

public static void main(String[] args) { 
    Board b = new Board(); 
    Board c = b; 

    System.out.println("BEFORE++: b.count = " + b.count); 
    System.out.println("BEFORE++: c.count = " + c.count); 

    b.count++; 

    System.out.println("AFTER++: b.count = " + b.count); 
    System.out.println("AFTER++: c.count = " + c.count); 
} 

public static class Board { 
    public int count = 0; 
} 

Sorties:

BEFORE++: b.count = 0 
BEFORE++: c.count = 0 
AFTER++: b.count = 1 
AFTER++: c.count = 1 
Questions connexes