Função de sobrecarga int… e longa… simultaneamente

Eu quero criar duas funções, digamos

long min(long...); int min(int...); 

Mas quando eu tento invocar o segundo, ou seja, min(1, 5) , recebo uma chamada de método ambígua

Existe solução alternativa, exceto renomear?

É um bug conhecido

O comportamento que você descreve é ​​um bug que foi corrigido com o Java 7. Veja os detalhes nas notas de lançamento , seção “Mudanças na Seleção de Método Mais Variável Variável”.

A razão pela qual deve compilar

A arriedade variável vem por último na determinação do método mais específico. As regras para determinar qual método vararg se aplica quando existem várias são definidas no JLS 15.12.2.4 – aqui está um extrato:

Um método de membro de aridade variável chamado m é mais específico do que outro método de membro de aridade de variável com o mesmo nome se:
– […]
– Um método membro possui k parâmetros e o outro tem n parâmetros, onde n ≥ k e:

  • Os tipos dos parâmetros do primeiro método são U1, …, Uk-1, Uk [].
  • Os tipos dos parâmetros do outro método são T1, …, Tn-1, Tn [].
  • Para todo j de 1 a n, Uj <: Tj

No seu caso, k = n, e U1[] = int[] e T1[] = long[] então a determinação pode ser feita se int <: long ou o contrário.

Em outras palavras, o tipo considerado não é int[] vs. long[] mas int vs long . E acontece que int <: long então o método int... deve ser escolhido e deve compilar.

Conclusão:

O código deve (e faz) compilar bem com o Java 7, mas não compilará com o Java 5 ou 6. O código abaixo imprime int com o Java 7:

 public class Test1 { public static void main(String[] args) { new Test1().m(1, 2); } int m(int... i) { System.out.println("int"); return 0; } long m(long... i) { System.out.println("long"); return 0; } } 

O problema é quando você invoca esses methods com um integer , nenhum dos methods fornece correspondência exata para o argumento, como você usou var-args . Além disso, ambos os var-args podem ter valores int separados por vírgulas como argumento. Daí o erro de ambiguous method .

Quando você chama o método sobrecarregado, o Compiler escolhe a exact match primeiro. Então, o nearest type a ser lançado.

Agora, como var-args é apenas uma array , o compilador não pode decidir qual array usar ao passar um valor integer . Como, nenhum dos arrays pode ser considerado como exact match ou nearest conversion . Portanto, é necessário o método elegível para a chamada.

Existem muito mais regras sobre a method invocation do method invocation em caso de Overloading . Você pode aprender com a Java Language Specification .


Como na resposta de @assylias, este problema foi corrigido no Java 7. Mas não funcionará na versão Java <7.

Tente isso

 public class Test { /** * @param args the command line arguments */ public static void main(String[] args) { new Test().m(100L,512L); new Test().m(100,512); } int m(int... i) { System.out.println("int"); return 0; } long m(long... i) { System.out.println("long"); return 0; } } 

Essas assinaturas de método são exclusivas e são sobrecargas de método válidas.

O problema deve estar no argumento de chamada do método. Meu palpite é que você está chamando o método com um literal, como:

 min(100) 

E isso não acontece porque 100 é um literal inteiro, mas é automaticamente convertido para um longo.

Desambiguar as chamadas de método usando L no final de literais longos deve corrigir o problema:

 min(100L) 

Além disso, você poderia tornar as chamadas explícitas usando o Java Object Integer e Long e deixar a autoboxing cuidar da conversão para tipos primitivos:

 min(new Long(100)) min(new Integer(100))