Ricerca…


introduzione

Questo articolo discute di getter e setter; il modo standard per fornire accesso ai dati nelle classi Java.

Aggiungere getter e setter

L'incapsulamento è un concetto base in OOP. Si tratta di avvolgere dati e codice come una singola unità. In questo caso, è buona norma dichiarare le variabili come private e quindi accedervi tramite Getters e Setters per visualizzarle e / o modificarle.

public class Sample {
  private String  name;
  private int age;

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Non è possibile accedere a queste variabili private direttamente dall'esterno della classe. Quindi sono protetti da accessi non autorizzati. Ma se vuoi vederli o modificarli, puoi usare Getters e Setter.

getXxx() metodo getXxx() restituirà il valore corrente della variabile xxx , mentre è possibile impostare il valore della variabile xxx utilizzando setXxx() .

La convenzione di denominazione dei metodi è (nella variabile di esempio è chiamata variableName ):

  • Tutte le variabili non boolean

     getVariableName()   //Getter, The variable name should start with uppercase
     setVariableName(..) //Setter, The variable name should start with uppercase
    
  • variabili boolean

      isVariableName()     //Getter, The variable name should start with uppercase
      setVariableName(...) //Setter, The variable name should start with uppercase
    

I getter e i setter pubblici fanno parte della definizione di proprietà di un bean Java.

Usare un setter o un getter per implementare un vincolo

Setter e Getter consentono a un oggetto di contenere variabili private a cui è possibile accedere e modificarle con restrizioni. Per esempio,

public class Person {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(name!=null && name.length()>2)
           this.name = name;
    }
}

In questa classe Person , c'è una singola variabile: name . È possibile accedere a questa variabile utilizzando il metodo getName() e modificata utilizzando il metodo setName(String) , tuttavia, l'impostazione di un nome richiede che il nuovo nome abbia una lunghezza maggiore di 2 caratteri e non sia null. L'uso di un metodo setter invece di rendere pubblico il name della variabile consente ad altri di impostare il valore del name con determinate restrizioni. Lo stesso può essere applicato al metodo getter:

public String getName(){
   if(name.length()>16)
      return "Name is too large!";
   else
      return name;
}

Nel metodo getName() modificato sopra, il name viene restituito solo se la sua lunghezza è minore o uguale a 16. In caso contrario, viene restituito "Name is too large" . Ciò consente al programmatore di creare variabili che siano raggiungibili e modificabili come desiderano, impedendo alle classi client di modificare indesideratamente le variabili.

Perché usare getter e setter?

Considera una classe base contenente un oggetto con getter e setter in Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

Non possiamo accedere alla variabile count perché è privata. Ma possiamo accedere ai metodi getCount() e setCount(int) perché sono pubblici. Per alcuni, questo potrebbe sollevare la domanda; perché introdurre l'intermediario? Perché non limitarsi a renderle pubbliche?

public class CountHolder {
  public int count = 0;
}

A tutti gli effetti, questi due sono esattamente gli stessi, dal punto di vista della funzionalità. La differenza tra loro è l'estensibilità. Considera cosa dice ogni classe:

  • Primo : "Ho un metodo che ti darà un valore int e un metodo che imposterà quel valore su un altro int ".
  • Secondo : "Ho un int che puoi impostare e ottenere come ti pare."

Questi potrebbero sembrare simili, ma il primo è in realtà molto più custodito nella sua natura; esso permette solo di interagire con la sua natura interna in quanto impone. Questo lascia la palla nel suo campo; può scegliere come si verificano le interazioni interne. Il secondo ha esposto esternamente la sua implementazione interna e ora non è solo incline agli utenti esterni, ma, nel caso di un'API, si impegna a mantenere tale implementazione (o altrimenti a rilasciare un'API compatibile non retrocompatibile).

Consideriamo se vogliamo sincronizzare l'accesso alla modifica e all'accesso al conteggio. Nel primo, questo è semplice:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

ma nel secondo esempio, questo è ora quasi impossibile senza passare e modificare ogni luogo in cui viene fatto riferimento alla variabile count . Peggio ancora, se questo è un oggetto che stai fornendo in una biblioteca per essere consumato da altri, non hai un modo di eseguire quella modifica, e sei costretto a fare la difficile scelta di cui sopra.

Quindi elemosina la domanda; le variabili pubbliche sono sempre una buona cosa (o, almeno, non sono cattive)?

Non sono sicuro Da un lato, è possibile visualizzare esempi di variabili pubbliche che hanno superato la prova del tempo (IE: la variabile out a cui fa riferimento in System.out ). Dall'altro, fornire una variabile pubblica non dà alcun beneficio al di fuori del sovraccarico estremamente minimo e della potenziale riduzione del prolisso. La mia linea guida qui sarebbe che, se hai intenzione di rendere pubblica una variabile, dovresti giudicarla contro questi criteri con estremo pregiudizio:

  1. La variabile dovrebbe avere alcuna ragione plausibile per cambiare mai nella sua attuazione. Questo è qualcosa che è estremamente facile da rovinare (e, anche se lo fai nel modo giusto, i requisiti possono cambiare), motivo per cui i getter / setter sono l'approccio comune. Se si ha una variabile pubblica, è necessario pensarci sopra, specialmente se rilasciata in una libreria / framework / API.
  2. La variabile deve essere referenziata abbastanza frequentemente che i guadagni minimi derivanti dalla riduzione della verbosità lo giustificano. Non penso nemmeno che l'overhead per l'utilizzo di un metodo rispetto al riferimento diretto debba essere considerato qui. È troppo trascurabile per quello che valuterei prudentemente per il 99,9% delle applicazioni.

Probabilmente c'è più di quello che non ho considerato in cima alla mia testa. Se hai dubbi, usa sempre getter / setter.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow