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?
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…
Enfim…
espero ter ajudado
diegohsi
Não sabia que o varargs retornava um array
Obrigado pela dica
ViniGodoy
diegohsi:
Não sabia que o varargs retornava um array
Obrigado pela dica
Ele não retorna. Na verdade, ele se transforma num array.
diegohsi
ViniGodoy:
diegohsi:
Não sabia que o varargs retornava um array
Obrigado pela dica
Ele não retorna. Na verdade, ele se transforma num array.
Nossa, como que acontece essa façanha ?
ViniGodoy
Durante a compilação.
O compilador transforma isso:
public int metodo(int ... x) {
//Faz qualquer coisa
}
metodo(1, 2, 3);
Nisso aqui:
public int metodo(int[] x) {
//Faz qualquer coisa
}
metodo(new int[] {1, 2, 3});
Tanto que se você fizer uma declaração com array junto da de varargs, ele acusará ambiguidade.
public int metodo(int ... x) {
//Faz qualquer coisa
}
public int metodo(int[] x) { //Ops, ambíguo. Igual ao de cima.
//Faz qualquer coisa
}
diegohsi
ViniGodoy:
Durante a compilação.
O compilador transforma isso:
public int metodo(int ... x) {
//Faz qualquer coisa
}
metodo(1, 2, 3);
Nisso aqui:
public int metodo(int[] x) {
//Faz qualquer coisa
}
metodo(new int[] {1, 2, 3});
Tanto que se você fizer uma declaração com array junto da de varargs, ele acusará ambiguidade.
public int metodo(int ... x) {
//Faz qualquer coisa
}
public int metodo(int[] x) { //Ops, ambíguo. Igual ao de cima.
//Faz qualquer coisa
}
Muito obrigado pelo esclarecimento vinigodoy foi de muita importância, isso seria uma bela questão para a certificação.
Jaba
damianijr:
transformando o varargs num array de mesmo tipo… até ai tudo bem né?
e devido ao autoboxing… ele acaba se perdendo…
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?