Oggetti mutabili: setter e getter

4

È una buona pratica avere un metodo setter di questo tipo? Con i tipi primitivi, è ovviamente buono, ma quando si dispone di un setter per un campo che contiene un riferimento all'oggetto mutabile, questo potrebbe non funzionare: il chiamante potrebbe modificare l'oggetto dopo averlo passato al metodo setField .

class Myclass{
   private MyOtherClass field;

   public setField(MyOtherClass field){
      this.field = field;
   }
}

È la cosa giusta chiamare semplicemente clone() (supponendo che MyOtherClass abbia solo campi di tipo primitivo)?

public setField(MyOtherClass field) {
    this.field = field.clone();
}
    
posta user4205580 31.03.2016 - 20:31
fonte

2 risposte

3

Se la tua classe è una struttura dati, ovviamente va bene farlo. Java Map ha un metodo put, che memorizza un riferimento. Se modifichi quel riferimento, ti aspetteresti di riavere l'oggetto modificato quando chiami Map.get ().

Se la tua classe è un'auto, e stai impostando i pneumatici, allora bene, il problema c'è: cosa succede se imposto il pneumatico e poi in un'altra parte del programma lo modifico? In questo caso (quando ci sono effetti collaterali), se il risultato è incoerenza, allora no, il setter non dovrebbe essere lì.

Penso che quello che chiedi sia un po 'ampio, perché ci sono casi in cui dovresti essere cauto e gli altri in cui è perfettamente valido. I setter di quel tipo esistono e sono dappertutto in Java.

Forse una soluzione migliore è passare in una classe che è immutabile (tutti i suoi campi sono definitivi) se vuoi evitare effetti collaterali. Se stavo usando un'API, non mi aspetterei che tutti i setter clonino i miei oggetti!

Esempio:

hai una classe Person . Può avere un JobPlace o no. Conosci il lavoro che una persona avrà quando lo creerai? Molto probabilmente no. Inoltre, la persona può cambiare lavoro? Sicuro.

Questo giustifica un person.setJob(job) . Ora la persona ha un riferimento al suo lavoro, ma cosa succede se il lavoro stesso cambia? Ad esempio, la società potrebbe cambiare nome. Person ha solo bisogno di conoscere l'interfaccia di JobPlace per funzionare, quindi il lavoro stesso può cambiare e se diversi Person hanno lo stesso riferimento a JobPlace , allora devi cambiarlo solo in un posto.

    
risposta data 31.03.2016 - 20:47
fonte
-2
    class Myclass{
       private MyOtherClass field; 

questa è la variabile che prima si inizializza come. In questo caso, il campo è una variabile privata di tipo MyOtherClass (questo è il tipo che hai creato, quindi questo NON è un tipo primitivo). Dato che non hai impostato un campo uguale a una variabile finale , puoi impostarlo uguale a qualsiasi cosa tu voglia, e per farlo puoi usare un costruttore. Quindi, si usa "this.field = field". Puoi anche fare questo:

 public Myclass(MyOtherClass football)
 {
     field = football;
 }
Il campo

è la variabile che hai creato e da quel momento in poi, hai impostato un campo uguale al tuo parametro. Pensa che non è diverso da questo.field = campo (c'è una differenza, ma facciamo un passo alla volta e capiamo prima questo, per evitare confusione).

quindi puoi usare questo:

class MyClass{
    private MyOtherClass field;

    public Myclass(MyOtherClass field)
    {
        this.field = field;
    }
}

O puoi usare questo:

class MyClass{
    private MyOtherClass field;

    public Myclass(MyOtherClass football)
    {
        field = football;
    }
}

E NON clona in questo modo. Questo non è ciò che significa clone (il modo in cui si utilizza il clone può causare ulteriore confusione e problemi in seguito nei progetti di codifica). Si prega di prendere un po 'di tempo per leggere su clone.

    
risposta data 01.04.2016 - 06:17
fonte

Leggi altre domande sui tag