Está sobrecarregando realmente a única maneira de obter valores padrão para os parâmetros do método em Java?

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu sou muito novo para Java e para Python e PHP, eu estou acostumado a valores padrão para parâmetros de função.

Então, eu tenho o hábito de escrever métodos que são projetados para ser chamado de situações ligeiramente diferentes em que pretende definir apenas alguns dos valores. Por exemplo, no meu código PHP, isso seria comum onde eu tenho métodos de fábrica que fornecem instâncias de objetos com propriedades ligeiramente diferentes.

Em Java, ao que parece, eu tenho que ter um método que espera que todos os parâmetros e, em seguida, diversas variações sobrecarregado que iria chamar esse método com alguns dos parâmetros definidos para os padrões e alguns fornecido pelo chamador. Que é, bem, OK, mas pode ficar em meus nervos às vezes.

Eu me lembro que isso já me incomodou em alguns breves excursões para C ++ e ActionScript. Agora, os desenvolvedores Java mais experientes têm algum atalho para isso?

Parece-me que, tecnicamente, a pergunta foi respondida pela soma de todas as mensagens como "Sim, é". Eu abri um post wiki abaixo para coletar as várias soluções alternativas, por favor contribua se quiser. Eu achei tudo isso muito útil como uma inspiração e de exemplo para construções típicas Java de aprendizagem.

Foi útil?

Solução 6

Parece que, "Sim, é", exceto:

Efeitos semelhantes podem ser alcançados com varargs como sugerido por Paul Whelan ou definindo um tipo extra de carregar os parâmetros como campos com os valores padrão apropriados como sugerido por Jon Skeet. Boris Pavlovic acrescenta que o tipo dele poderia ser uma classe estática interna para manter as coisas ordenadamente no lugar certo.

Contras (Note-se que toda esta questão não é sobre as eventuais incidências graves, apenas sobre ajustes convenientes):

VarArgs parece mais adequado para a passagem de uma lista de comprimento variável de valores que têm forma muito semelhante e significado principalmente equivalente, como uma lista de nomes. Se usado com o propósito declarado na pergunta, o método teria que executar várias verificações na lista, a fim de interpretá-lo, o que não mais parece, mas menos conveniente.

Um tipo especial transportando os parâmetros parece mais útil se o tipo resultante poderia ser de outros usos do que apenas sendo passado para um método particular, ou quando é um conjunto mais complexo de parâmetros. Se há 2-4 parâmetros e alguns podem ter valores padrão, ele ainda parece um pouco mais conveniente para a sobrecarga, mas que pode ser uma questão de gosto pessoal.

Outras dicas

Outra opção é uma variação sobre o padrão do construtor - você tem um tipo que representa todos os parâmetros, construir uma instância desse tipo (cujo padrão em conformidade), defina as propriedades que deseja e, em seguida, passar o resultado para o método original ou adicionar um método no "tipo de parâmetro" para chamar o método para você.

Você pode ver isso em ação nas bibliotecas padrão, com o ProcessBuilder e Process classes.

ver varargs

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

(URL atualizado; este comentário adicionado porque stackoverflow requer> 30 caracteres)

Para tornar isso mais simples, eu criei uma anotação para valores padrão e um processador de anotação que gera uma superclasse com os métodos sobrecarregados. Por exemplo:

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

que gera (em uma superclasse gerado)

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) ;

http://code.google.com/p/javadude/wiki/ anotações - Scott

Pode ser muito difícil tentar traduzir o seu processo, embora a partir de um langauge para outro. Você pode, como outros já apontaram, fazer algumas arounds trabalho para talvez conseguir o que você quer ... mas quanto mais cedo você "aceitar" a maneira que Java é projetado para trabalhar o melhor para você vai ser quando trabalhando em Java.

Eu tive que fazer algumas coisas PHP ... me incomodou para nenhum fim que eu não poderia obtê-lo para fazer o que eu queria ... por isso vai nos dois sentidos.

O maior obstáculo que você vai correr em é provavelmente a tipagem estática. Há coisas que você pode tentar fazer para trabalhar em torno dele, mas no final eles serão uma grande hack.

Nos primeiros dias de pessoas C ++ tentou convencer C ++ para se comportar como Smalltalk ... não funcionou muito bem. Nos primeiros dias se as pessoas Java tentaram tomar o seu conhecimento C ++ e usá-lo em Java ... não funcionou muito bem (que é duplamente frustrante como as línguas são muito semelhantes na superfície).

O meu conselho, por sua codificação Java aprender a programa como um desenvolvedor Java, em vez de um desenvolvedor PHP.

Para o seu problema imediato, é possível que você deve realmente ser retuning aulas differnt da fábrica em vez de criar o mesmo tipo de objeto com variáveis ??differnt definidos?

Enquanto você código de uma maneira OO você não vai perder valores padrão em Java. argumentos padrão são úteis apenas no estilo de codificação processual.

Em OO em vez de passar o estado através dos métodos / procedimentos, o estado já está no objeto que você chama, ou os objetos que passam como parâmetros. Na maioria das vezes você não precisa de mais do que 1 ou 2 parâmetros em seus métodos.

Se você deseja configurar alguma objeção antes de usá-lo, você iria construí-lo com um construtor simples, e de chamadas diferentes setters. Isso torna o código muito mais legível (porque você vê os nomes setter), em comparação a chamar um construtor ter muitos argumentos. E, no caso de um novo atributo vem mais tarde, você pode adicionado ao seu objeto sem ter que modificar seus métodos de fábrica existentes.

Sim por do oop sua a sobrecarga que é o único caminho para a utilização paramater padrão em java. Mas aqui está o truque para você. Se você usar a sobrecarga e você quer ter parâmetro padrão. Então você vai acabar

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) { }

Mas 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);
 }
}

A saída do código acima será

false
true

Para obter exemplos mais simliar e visita explicação java-default-parâmetro de valores

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top