public class Devk{
public static void tMeth(Integer... i){
System.out.print("A");
}
public static void tMeth(int... i){
System.out.print("B");
}
public static void main(String args[]){
tMeth(Integer.valueOf("7"));
}
}
De acordo com o compilador, dá erro porque os dois métodos são compativeis com o parâmetro passado.
Mas, o Integer.valueOf retorna um Wrapper do argumento passado, certo?
Bom, pensando nisso, a regra para ampliação é: procura um tipo que encaixe ( exemplo: int em um long, byte em um short ), se não achar, amplia e tenta achar um Wrapper, se não achar, procura um Var-Arg…
Ai é que tá: quando ele vai procurar o var-arg, ele acha dois, mais ele não deveria chamar o var-arg do empacotador, já que o outro é apenas um sub-tipo?
Porque os dois métodos são considerados para o que está sendo passado e dá erro?
o que acontece é que em tempo de compilação o compilador verá os metodos assim:
public static void tMeth(Integer[] i){
System.out.print("A");
}
public static void tMeth(int[] i){
System.out.print("B");
}
transformando o varargs num array de mesmo tipo… até ai tudo bem né?
e devido ao autoboxing… ele acaba se perdendo…
então quando você passou seu parâmetro para o método, Integer.valueOf(“7”), ele está vendo algo do tipo: Integer[] x = { Integer.valueOf(“7”) };
que casa exatamente com os 2 métodos visto pelo compilador… e ai ele se perde… pois não pode tomar uma decisão certa sobre o caso
só mais um detalhe…
Na verdade ele amplia e tenta encaixar no menor tipo possivel, passou um byte e tem um método com int e com long, ele encaixa no INT…
Agora
Na verdade ele não vai ampliar para tentar achar um wrapper…
ele vai procurar um wrapper de mesmo tipo…
no caso se você passou um byte… ele vai procurar um Byte… não vai amplicar o byte para int e achar o wrapper Integer…
[quote=damianijr]transformando o varargs num array de mesmo tipo… até ai tudo bem né?
e devido ao autoboxing… ele acaba se perdendo…[/quote]
Não transforma o array de mesmo tipo… Eu tenho então um Array de tipos primitivos “int” e um array de wrappers “Integer”. int é diferente de Integer, não vejo o porque dele definir isso como ambiguo, isso deveria ser sobrecarga.
E se eu precisar de dois métodos iguais com var-args diferentes, ou seja, sobrecarregado, para que ele faça coisas diferentes dependendo do argumento?