Pq isso é possivel 2?

18 respostas
F

Ai mestre Vinny , fiquei com mais uma duvida, pq neste caso o compildor prefere o Wrapper?se retirar o paramentro dos metodos x() ele ira preferir
o metodo sobrescrito da classa anonima

class A{
    void x(Integer x){
      System.out.println("Integer x");  
    }
}

  class NewClass{
   A n=new A(){
        void x(int x){
      System.out.println("int x");  
    }
        
        
   };
   void m(){
      
     n.x(4);  
   }
        
       public static void main(String...a){
         new NewClass().m();
           
       }

        
     }

18 Respostas

anderson.bonavides

Rapaz pelo que eu entendi ele a chamada ao método n.x(4) da prioridade ao método x da classe A quando vc retira o parametro do método x o único que pode atender é o método da classe anônima e isso é bem óbvio.
Mas se vc fizer a seguinte modificação na classe A:

class A {
	void x(Integer i){
		System.out.println("integer x");
	}
	void x(int i){
		System.out.println("int");
	}
	void x(int... i){
		System.out.println("varargs");
	}
	void x(long l){
		System.out.println("long");
	}
	void x(Long i){
		System.out.println("Long Wrapper");
	}
}

Qual irá imprimir?
Imprimirá “int” já que java reconhece o parametro do método chmado como um int. Caso não tivese o método void x(int i) ele imprimiria “long”. Isso pq um long pode receber um int. E se por acaso não tivesse o método void x(long) ele imprimiria “Integer x” e caso não tivese o metodo void x(Integer x) ele imprimiria “varargs”. E se não tivese o método void x(varargs) ele imprimiria?
Resposta: Não imprimiria. Não é possivel fazer unbox e depois converter para wraper e depois passar para um Long. Axo que o livro da kathy fala algo +/- assim. Caso eu estiver errado nesta frase alguêm me corrija. =]

Espero ter ajudado. t+

F

anderson.bonavides:
Rapaz pelo que eu entendi ele a chamada ao método n.x(4) da prioridade ao método x da classe A quando vc retira o parametro do método x o único que pode atender é o método da classe anônima e isso é bem óbvio.
Mas se vc fizer a seguinte modificação na classe A:

Ei cara ,nao entendi o quis dizer no começo, por favor entao me explique pq quando eu tiro o paramentro do metodo x() ele chama o da subclasse anonima??E porque ele prefere o wrapper ao invez de casar com o metodo int !!
valeu gente boa!!

anderson.bonavides

Quando vc tira o paremetro do metodo na classe A void x(Integer i) e deixa void x() ele procura a assinatura do método que mais se encaixa. Nesse caso ele encontra o método da classe Anonima que tem um parametro void x(int x). Não sei te informar se polimorfismo tem haver com isso esse tipo de situação. Já que não tem herança. E pelo fato de procurar assinatura ele procura da seguinte forma. Ve se vc compreende:

se (encontrar o mesmo primitivo) então
     chama primitivo
senao 
       se (chama tipo q pode receber) então
             para um char chama um shor, para um int chama um long para um doble chama um float...
       senão 
             se(chama tipo tipo wraper)então
                 Ingeger, Character, Float, Double, Short...
             senão 
                  se(chama um tipo varargs)então
                       int...x,double...d, e assim sucessivamente...
                  senão
                       se(nao pode chamar um tipo adequado)entao
                           essa situação acontece quando nao encontra um tipo adequado da variável
                           acontece erro de compilação.

Lembra que eu falei também que na escolha não é possível converter para um tipo Integer de depois passar para um Long? Pois é isso tbm eh erro de compilação.

Essas são as prioridades na escolha de um método adequado. Espero ter te ajudado.

anderson.bonavides

Só mais uma coisa! Vc compreendeu que o metodo void m() faz uma chamada a um segundo método n.x(4);

???

Guilherme_Gomes

Mas onde ele está retirando parâmetro de x()? Está como x(integer) e x(int)…

anderson.bonavides

Ele soh supos se tirar o parametro do método x pq chamaria o método da classe anonima! Entendeu?

mateusbrum

Bom dia!
O compilador define o método a ser chamado em tempo de execusão, baseado-se na referencia e não no objeto, por isso ocorre este resultado.
Ou seja, a instancia “a” não tem nenhum método acessível com o parâmetro do tipo primitivo “int”, então o compilador NÃO pode escolher qual método chamar.

A

Olá pesssoal,
Acho que eh meu primeiro post neste Forum.
Bom…até onde sei, qdo vc muda os parametros (ex. Integer x int) isso eh overload e portanto, o metodo eh chamado baseado na referencia. Apenas metodos override sao chamados baseados na instancia do objeto.

Alexsandra

F

anderson.bonavides:
Quando vc tira o paremetro do metodo na classe A void x(Integer i) e deixa void x() ele procura a assinatura do método que mais se encaixa. Nesse caso ele encontra o método da classe Anonima que tem um parametro void x(int x). Não sei te informar se polimorfismo tem haver com isso esse tipo de situação. Já que não tem herança. E pelo fato de procurar assinatura ele procura da seguinte forma. Ve se vc compreende:

se (encontrar o mesmo primitivo) então
     chama primitivo
senao 
       se (chama tipo q pode receber) então
             para um char chama um shor, para um int chama um long para um doble chama um float...
       senão 
             se(chama tipo tipo wraper)então
                 Ingeger, Character, Float, Double, Short...
             senão 
                  se(chama um tipo varargs)então
                       int...x,double...d, e assim sucessivamente...
                  senão
                       se(nao pode chamar um tipo adequado)entao
                           essa situação acontece quando nao encontra um tipo adequado da variável
                           acontece erro de compilação.

Lembra que eu falei também que na escolha não é possível converter para um tipo Integer de depois passar para um Long? Pois é isso tbm eh erro de compilação.

Essas são as prioridades na escolha de um método adequado. Espero ter te ajudado.

Se nao me engano a piramide de prioridade é :1)procura pelo mesmo tipo,nao encontra entao 2) faz uma ampliacao,nao pode ampliar 3)procura casar com wrapper,nao encontra 4)procura casar com Number,nao econtra 5)procura casar com Object ,nao econtra,6)procura casar com varg-args.

F

alexsandra:
Olá pesssoal,
Acho que eh meu primeiro post neste Forum.
Bom…até onde sei, qdo vc muda os parametros (ex. Integer x int) isso eh overload e portanto, o metodo eh chamado baseado na referencia. Apenas metodos override sao chamados baseados na instancia do objeto.

Alexsandra


E verdade tinha me esquecido!!!me confundi afinal o qd istancio new A criado a classe anonima é como se fosse uma sub-classe!!!cara é facil se confundir mesmo nessa parte!!

anderson.bonavides

E só corrigindo uma coisa que eu falei errada, ele quiz dizer que quando tirar o parametro do método x da classe A e não da classe anônima. E para o fabioEM se vc prestar atenção ai vai verificar que falei exatamente do jeito que vc colocou com a exceção de Number e Objetc que passei despecebido.

F

ok valeu cara!Tavo so acrescentando!

anderson.bonavides

Mas foi legal vc ter acrescentado.
:wink:

F

Bom Anderson acho que tu tambem estas estudando pelo livro da katy nao?Bom tem uma coisa que nao me é clara.
É o seguinte ,na pagina 371 assunto classes anonimas simples,versao 2 diz:

uma classe interna anonima nao pode nem estender uma classe e nem implementar uma interface ao mesmo tempo.
mas se eu fizer o seguinte:

class SerVivo{
    
}
interface Respirar{
    
}
class Homen extends SerVivo implements Respirar{
    
}
 public class NewClass87{  
       Homen h=new Homen(){//classe anonima que extende outra e implementa uma interface
        };
     public static void main(String...a){ 
             }  
  }

sea alguem puder esclarecer sera muito bem vindo galera!!

anderson.bonavides

Essa sinceramente não sei pq foi um assunto que faltei revisar. Ainda vou dar uma olhada.

victorwss

uma classe interna anonima nao pode nem estender uma classe e nem implementar uma interface ao mesmo tempo.
mas se eu fizer o seguinte:

class SerVivo{  
      
}  
interface Respirar{  
      
}  
class Homen extends SerVivo implements Respirar{  
      
}  
public class NewClass87{    
       Homen h=new Homen(){//classe anonima que extende outra e implementa uma interface  
        };  
     public static void main(String...a){   
             }    
  }

sea alguem puder esclarecer sera muito bem vindo galera!!

Essa é fácil. O que acontece é que você declara uma classe anônima ou como uma subclasse especial de uma outra classe OU como um implementador de uma interface. Você não pode declará-la como uma subclasse especial de uma classe E AO MESMO TEMPO implementador de uma interface. Observe que isto é diferente de ser subclasse de alguma outra classe que implementa a interface.
O que a Kathy quis dizer é mais ou menos isso:

class X {
    absrtact class A { public abstract void x(); }
    interface B { public void y(); }

    // Classe anônima é subclasse de A.
    A a = new A() {
        public void x() {}
    }

    // Classe anônima implementa B.
    B b = new B() {
        public void y() {}
    }

    // Não funciona.
    B c = new A+B() {
        public void x() {}
        public void y() {}
    }

    // Também não funciona.
    B d = new A() implements B {
        public void x() {}
        public void y() {}
    }
}
F

valeu cara mas desculpas nao entendi mesmo e
o que quis dizer com esse tipo de codigo

B c = new A+B() { 
   B d = new A() implements B {
anderson.bonavides

fabioEM:

valeu cara mas desculpas nao entendi mesmo e
o que quis dizer com esse tipo de codigo

B c = new A+B() { B d = new A() implements B {

victorwss não sei também não sei mesmo oq ele quiz dizer a primeira linha, mas na segunda ele quiz dizer que na classe interna anônima vc não pode utlilizar a palavra chave implements.

Acho que ele quiz dizer quanod faz B c = new A+B() que vai ter coisas da classe A e também da interface B. O que é errado na classe interna anônima

Criado 27 de dezembro de 2007
Ultima resposta 16 de jan. de 2008
Respostas 18
Participantes 6