Me deparei com algum código Java que tinha a seguinte estrutura:
public MyParameterizedFunction(String param1, int param2)
{
this(param1, param2, false);
}
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
//use all three parameters here
}
Eu sei que em C ++ posso atribuir um parâmetro a um valor padrão. Por exemplo:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
O Java suporta esse tipo de sintaxe? Existem razões pelas quais essa sintaxe de duas etapas é preferível?
public MyParameterizedFunction(String param1, int param2)
é uma declaração de construtor, não método.Respostas:
Não, a estrutura que você encontrou é como o Java lida com isso (ou seja, com sobrecarga em vez de parâmetros padrão).
Para construtores, consulte Dica do Item 1 do Java Efetivo: Guia da Linguagem de Programação (Considere métodos estáticos de fábrica em vez de construtores) se a sobrecarga estiver ficando complicada. Para outros métodos, renomear alguns casos ou usar um objeto de parâmetro pode ajudar. É quando você tem complexidade suficiente que diferenciar é difícil. Um caso definido é onde você deve diferenciar usando a ordem dos parâmetros, não apenas o número e o tipo.
fonte
static
tudo é considerado prejudicial em 2015. DigiteBuilder
instâncias fluentes seguras que imponham contratos de construção completos e válidos agora são uma solução muito melhor.new
. Eles são usados o tempo todo no novo código. Os construtores de objetos de valor simples geralmente são o resultado de excesso de engenharia.Não, mas você pode usar o Padrão do Construtor , conforme descrito nesta resposta do estouro de pilha .
Conforme descrito na resposta vinculada, o Builder Pattern permite escrever código como
em que alguns campos podem ter valores padrão ou serem opcionais.
fonte
Student s1 = new Student().age(16);
, isso deixaria você com um aluno sem nome, o que pode ser ruim. Se não estiver ruim, sua solução está correta.Existem várias maneiras de simular parâmetros padrão em Java:
Sobrecarga de método.
Uma das limitações dessa abordagem é que ela não funcionará se você tiver dois parâmetros opcionais do mesmo tipo e qualquer um deles puder ser omitido.
Varargs.
a) Todos os parâmetros opcionais são do mesmo tipo:
b) Os tipos de parâmetros opcionais podem ser diferentes:
A principal desvantagem dessa abordagem é que, se os parâmetros opcionais forem de tipos diferentes, você perderá a verificação de tipo estático. Além disso, se cada parâmetro tiver um significado diferente, você precisará de alguma maneira de distingui-lo.
Nulos. Para abordar as limitações das abordagens anteriores, você pode permitir valores nulos e, em seguida, analisar cada parâmetro em um corpo de método:
Agora todos os valores dos argumentos devem ser fornecidos, mas os padrão podem ser nulos.
Classe opcional. Essa abordagem é semelhante a nulos, mas usa a classe Java 8 Optional para parâmetros que possuem um valor padrão:
Opcional torna um contrato de método explícito para um chamador, no entanto, pode-se achar essa assinatura muito detalhada.
Padrão do construtor. O padrão do construtor é usado para construtores e é implementado através da introdução de uma classe Builder separada:
Maps. Quando o número de parâmetros é muito grande e, para a maioria deles, os valores padrão geralmente são usados, você pode passar argumentos de método como um mapa de seus nomes / valores:
Observe que você pode combinar qualquer uma dessas abordagens para obter um resultado desejável.
fonte
return this
fazer? Além disso, umaFooBuilder().setA("a").build();
vez que (por definição) o construtor é chamado primeiro eFooBuilder()
retorna um valor, isso não significa.setA("a"):
que não tem a chance de ser chamado?return this
retorna o mesmo objeto no qual o método foi chamado (no exemploFooBuilder
). Isso permite o encadeamento de métodos em uma instrução que atua no mesmo objeto:new FooBuilder().setA(..).setB(..).setC(..)
etc, em vez de chamar cada método em uma instrução separada.new FooBuilder()
retorna umFooBuilder
objeto no qual osetA
método é chamado. ComosetB
não é chamado,this.b
mantém o valor padrão. Finalmente, obuild
método é chamado nesseFooBuilder
objeto. Obuild
método cria e retorna umFoo
objeto que está definido para a variávelFoo foo
. Observe que oFooBuilder
objeto não está armazenado em nenhuma variável.Infelizmente não.
fonte
Infelizmente sim.
pode ser escrito em Java 1.5 como:
Mas se você deve ou não depender de como se sente sobre o compilador gerar um
para cada chamada.
Para vários parâmetros padrão:
pode ser escrito em Java 1.5 como:
Isso corresponde à sintaxe do C ++, que permite apenas parâmetros padrão no final da lista de parâmetros.
Além da sintaxe, há uma diferença em que isso verifica o tipo de tempo de execução para parâmetros padrão passados e o tipo C ++ os verifica durante a compilação.
fonte
assert
código em produção. Lance uma exceção.Não, mas você pode facilmente imitá-los. O que em C ++ foi:
Em Java, será uma função sobrecarregada:
Mencionado anteriormente, os parâmetros padrão causaram casos ambíguos na sobrecarga de funções. Isso simplesmente não é verdade, podemos ver no caso do C ++: sim, talvez ele possa criar casos ambíguos, mas esses problemas podem ser facilmente tratados. Simplesmente não foi desenvolvido em Java, provavelmente porque os criadores queriam uma linguagem muito mais simples como o C ++ - se eles tivessem razão, é outra questão. Mas a maioria de nós não acha que ele usa Java devido à sua simplicidade.
fonte
Você pode fazer isso no Scala, que é executado na JVM e é compatível com os programas Java. http://www.scala-lang.org/
ie
fonte
Não , mas a maneira mais simples de implementar isso é:
ou em vez do operador ternário , você pode usar
if
:fonte
Eu posso estar afirmando o óbvio aqui, mas por que não simplesmente implementar você mesmo o parâmetro "padrão"?
para o padrão, você usaria
e se você não gostaria de usar o padrão, usaria
fonte
//This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } }
//Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }
Como Scala foi mencionado, Kotlin também merece ser mencionado. Na função Kotlin, os parâmetros também podem ter valores padrão e podem até se referir a outros parâmetros:
Como o Scala, o Kotlin é executado na JVM e pode ser facilmente integrado aos projetos Java existentes.
fonte
Não.
Você pode obter o mesmo comportamento passando um objeto com padrões inteligentes. Mas, novamente, depende de qual é o seu caso.
fonte
Não. Em geral, o Java não possui muito (nenhum) açúcar sintático, pois eles tentaram criar uma linguagem simples.
fonte
const
egoto
ser reservado palavras-chave que nenhuma implementação? - Especialmenteconst
é algo que sinto muita falta -final
não é substituto e eles sabiam disso. - E se você tomou a decisão consciente de nunca implementargoto
, não precisará reservar a palavra-chave. - E mais tarde na equipe do Java, trapaceou, tornando o Label baseadobreak
econtinue
tão poderoso quanto um Pascalgoto
.Ao invés de usar:
Você pode utilizar a funcionalidade opcional do java tendo um único método:
A principal diferença é que você deve usar classes de wrapper em vez de tipos Java primitivos para permitir
null
entrada.Boolean
em vez deboolean
, emInteger
vez deint
e assim por diante.fonte
Não é suportado, mas existem várias opções, como o uso de padrão de objeto de parâmetro com algum açúcar de sintaxe:
Nesta amostra, construímos
ParameterObject
com valores padrão e os substituímos na seção de inicialização da instância de classe{ param1 = 10; param2 = "bar";}
fonte
Experimente esta solução:
fonte
Você pode usar o Java Method Invocation Builder para gerar automaticamente o construtor com valores padrão.
Basta adicionar @GenerateMethodInvocationBuilder à classe ou interface e o @Default aos parâmetros nos métodos em que você deseja valores padrão. Um construtor será gerado em tempo de compilação, usando os valores padrão que você especificou com suas anotações.
E então você pode invocar os métodos.
Ou defina qualquer um dos valores padrão para outra coisa.
fonte
Uma abordagem semelhante a https://stackoverflow.com/a/13864910/2323964 que funciona no Java 8 é usar uma interface com getters padrão. Isso será mais amplo em branco, mas é ridículo, e é ótimo para quando você tem várias instâncias em que deseja chamar a atenção para os parâmetros.
fonte
Agora dediquei algum tempo para descobrir como usá-lo com métodos que retornam valores, e ainda não vi nenhum exemplo até agora, achei que seria útil adicionar isso aqui:
fonte
Foi assim que eu fiz ... não é tão conveniente, talvez, ter um 'argumento opcional' contra o seu parâmetro definido, mas ele faz o trabalho:
Observe que eu posso invocar o mesmo nome de método com apenas uma string ou com uma string e um valor booleano. Nesse caso, definir wipeClean como true substituirá todo o texto em minha TextArea pela string fornecida. Definir o wipeClean como false ou deixar de fora todos juntos simplesmente anexa o texto fornecido à TextArea.
Observe também que não estou repetindo o código nos dois métodos, apenas adicionando a funcionalidade de poder redefinir a TextArea criando um novo método com o mesmo nome apenas com o booleano adicionado.
Na verdade, acho que isso é um pouco mais limpo do que se o Java fornecesse um 'argumento opcional' para nossos parâmetros, já que precisaríamos codificar valores padrão etc. Nesse exemplo, não preciso me preocupar com nada disso. Sim, adicionei outro método à minha turma, mas é mais fácil ler a longo prazo na minha humilde opinião.
fonte
NÃO, mas temos alternativas na forma de sobrecarga de função.
chamado quando nenhum parâmetro passou
chamado quando "a" parâmetro foi passado
chamado quando o parâmetro b passou
fonte
Existem meia dúzia ou mais de problemas como esse; eventualmente, você chega ao padrão estático de fábrica ... veja a API de criptografia para isso. É difícil explicar, mas pense da seguinte maneira: se você tem um construtor, padrão ou não, a única maneira de propagar o estado além dos chavetas é ter um Boolean isValid; (junto com o valor nulo como padrão v com falha no construtor) ou lança uma exceção que nunca é informativa ao recuperá-la dos usuários de campo.
Código correto, caramba, escrevo milhares de construtores de linha e faço o que preciso. Acho que usando isValid na construção de objetos - em outras palavras, construtores de duas linhas - mas, por algum motivo, estou migrando para o padrão de fábrica estático. Parece que você pode fazer muito se estiver em uma chamada de método, ainda há problemas de sync (), mas os padrões podem ser 'substituídos' melhor (mais seguro)
Eu acho que o que precisamos fazer aqui é resolver a questão de nulo como valor padrão em relação a algo String one = new String (""); como uma variável membro, em seguida, verifique nulo antes de atribuir a sequência passada ao construtor.
Muito notável a quantidade de ciência da computação estratosférica bruta feita em Java.
C ++ e assim por diante tem bibliotecas de fornecedores, sim. O Java pode superá-los em servidores de grande escala devido à sua enorme caixa de ferramentas. Estude os blocos estáticos do inicializador, fique conosco.
fonte
Não é suportado em java como em outro idioma para ex. Kotlin.
fonte
Você pode usar o seguinte-
fonte