Il sovraccarico è davvero l'unico modo per ottenere valori predefiniti per i parametri del metodo in Java?

StackOverflow https://stackoverflow.com/questions/618276

  •  03-07-2019
  •  | 
  •  

Domanda

Sono abbastanza nuovo su Java e da Python e PHP, sono abituato ai valori predefiniti per i parametri delle funzioni.

Quindi ho l'abitudine di scrivere metodi progettati per essere chiamati da situazioni leggermente diverse in cui si desidera impostare solo alcuni dei valori. Ad esempio, nel mio codice PHP, questo sarebbe comune quando ho metodi di fabbrica che forniscono istanze di oggetti con proprietà leggermente diverse.

In Java, a quanto pare, devo avere un metodo che prevede tutti i parametri e quindi diverse varianti sovraccaricate che chiamerebbero quel metodo con alcuni dei parametri impostati sui valori predefiniti e alcuni forniti dal chiamante. Va bene, ma a volte può innervosirmi.

Ricordo che questo mi ha già infastidito in alcune brevi escursioni in C ++ e ActionScript. Ora, gli sviluppatori Java più esperti hanno qualche scorciatoia per questo?

Mi sembra che, tecnicamente, alla domanda sia stata data una risposta dalla somma di tutti i post come " Sì, è " ;. Ho aperto un post wiki qui sotto per raccogliere le varie soluzioni alternative, per favore contribuisci se vuoi. Ho trovato tutto ciò molto utile come fonte di ispirazione e come esempio di apprendimento per costrutti Java tipici.

È stato utile?

Soluzione 6

Sembra, " Sì, è " ;, tranne:

Effetti simili potrebbero essere ottenuti con varargs come suggerito da Paul Whelan o definendo un tipo aggiuntivo che trasporta i parametri come campi con i valori predefiniti corretti come suggerito da Jon Skeet. Boris Pavlovic aggiunge che il suo tipo potrebbe essere una classe statica interna per mantenere le cose ordinatamente nel posto giusto.

Contro (nota che tutta questa domanda non riguarda implicazioni serie, ma solo utili modifiche):

I Vararg sembrano più adatti per passare un elenco di valori a lunghezza variabile che hanno una forma molto simile e un significato per lo più equivalente, come un elenco di nomi. Se utilizzato per lo scopo indicato nella domanda, il metodo dovrebbe eseguire vari controlli nell'elenco per interpretarlo, che non sembra più, ma meno conveniente.

Un tipo speciale che trasporta i parametri sembra molto utile se il tipo risultante potrebbe essere di altri usi oltre a essere passato a un metodo particolare o quando si tratta di un insieme di parametri più complesso. Se ci sono 2-4 parametri e alcuni possono avere valori predefiniti, sembra ancora un po 'più conveniente sovraccaricare, ma potrebbe essere una questione di gusti personali.

Altri suggerimenti

Un'altra opzione è una variazione sul modello del builder: hai un tipo che rappresenta tutti i parametri, costruisci un'istanza di quel tipo (che di default è di conseguenza), imposta le proprietà che desideri e quindi passa il risultato al metodo originale oppure aggiungi un metodo nel tipo di parametro " " per chiamare il metodo per te.

Puoi vederlo in azione nelle librerie standard, con ProcessBuilder e classi Process .

vedi varargs

http : //www.java-tips.org/java-se-tips/java.lang/using-the-varargs-language-feature.html

(URL aggiornato; questo commento è stato aggiunto perché stackoverflow richiede > 30 caratteri)

Per semplificare il tutto, ho creato un'annotazione per i valori predefiniti e un processore di annotazione che genera una superclasse con i metodi sovraccarichi. Ad esempio:

protected void process(
    Processor processor,
    String item,
    @Default("Processor.Size.LARGE") Size size,
    @Default("red") String color,
    @Default("1") int quantity) {
        ...
}

che genera (in una superclasse generata)

protected void process(sample.Processor processor, java.lang.String item)  {
    process(processor, item, Processor.Size.LARGE, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size)  {
    process(processor, item, size, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size, 
                       java.lang.String color)  {
    process(processor, item, size, color, 1);
}
protected abstract void process(sample.Processor processor, 
                                java.lang.String item, 
                                sample.Processor.Size size, 
                                java.lang.String color, 
                                int quantity) ;

Vedi http://code.google.com/p/javadude/wiki/ annotazioni - Scott

Può essere molto difficile provare a tradurre il tuo processo attraverso una lingua in un'altra. Come altri hanno sottolineato, puoi fare qualche soluzione per ottenere forse quello che vuoi ... ma prima accetti " accetta " il modo in cui Java è progettato per funzionare al meglio sarà quando si lavora in Java.

Ho dovuto fare alcune cose PHP ... mi ha infastidito fino in fondo che non sono riuscito a farlo fare quello che volevo ... quindi va in entrambe le direzioni.

L'ostacolo più grande che incontrerai è probabilmente la tipizzazione statica. Ci sono cose che puoi provare a aggirare, ma alla fine saranno un grande hack.

All'inizio del C ++ le persone cercavano di convincere il C ++ a comportarsi come Smalltalk ... non funzionava troppo bene. All'inizio se le persone Java cercavano di prendere le loro conoscenze C ++ e di usarle in Java ... non ha funzionato troppo bene (il che è doppiamente frustrante in quanto i linguaggi sono molto simili in superficie).

Il mio consiglio, per la tua codifica Java, impara a programmare come uno sviluppatore Java piuttosto che uno sviluppatore PHP.

Per il tuo problema immediato, è possibile che tu debba veramente risintonizzare classi diverse dalla fabbrica invece di creare lo stesso tipo di oggetto con variabili diverse impostate?

Finché codifichi in modo OO non perderai i valori predefiniti in Java. Gli argomenti predefiniti sono utili solo nello stile di codifica procedurale.

In OO invece di passare lo stato attraverso i metodi / procedure, lo stato è già nell'oggetto chiamato o negli oggetti passati come parametri. Il più delle volte non sono necessari più di 1 o 2 parametri nei metodi.

Se vuoi configurare il tuo oggetto prima di usarlo, lo costruiresti con un semplice costruttore e poi chiameresti setter diversi. Questo rende il codice molto più leggibile (perché vedi i nomi dei setter), rispetto al chiamare un costruttore con molti argomenti. E nel caso in cui un nuovo attributo venga successivamente, puoi aggiungerlo al tuo oggetto senza dover modificare i metodi di fabbrica esistenti.

Sì, da parte di oop è il sovraccarico che è l'unico modo per usare il parametro predefinito in java. Ma ecco l'hack per te. Se si utilizza il sovraccarico e si desidera avere un parametro predefinito. Quindi finirai

public void methodA(A arg1) { }
public void methodA( B arg2,) { }
public void methodA(C arg3) { }
public void methodA(A arg1, B arg2) { }
public void methodA(A arg1, C arg3) { }
public void methodA( B arg2, C arg3) { }
public void methodA(A arg1, B arg2, C arg3) { }

Ma usando varargs

public class DefaultValue
{
 public static void main(String[] args)
  {
       defaultParameter();
       defaultParameter(true);
  }

  public static void defaultParameter(Boolean …gender)
  {
       boolean genderBoolean = false; // It is the default value you want to give
       if(1 == gender.length)
       {
            genderBoolean = gender[0]; // Overrided Value
      }
       System.out.println(genderBoolean);
 }
}

L'output del codice sopra riportato sarà

false
true

Per ulteriori esempi e spiegazioni simliar visitare java-default-parametro-valori

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top