Questão estranha de Autobox

40 respostas
vanzella

Alguem poderia me falar a resposta e a explicação desse codigo?

public class Locura {
	
	public Locura(Long a, Long b)
	{
		System.out.println("Long a, Long b");
	}
	
	public Locura(long a, long b)
	{
		System.out.println("long a, long b");
	}
			
	public static void main(String[] args) {
		Long a = 10L;
		new Locura(a, 15L);
	}
}

40 Respostas

victorwss

Autoboxing+sobrecarga é sempre um problema.

A minha aposta é que o compilador emite um erro porque a chamada é ambígua, mas não tenho certeza (e no momento não tenho como testar). Para tirar a dúvida, tente compilar isso e vê o que acontece.

vanzella

Bom pelo que imagino o compilador fica confuso, se faz unbox ou autobox, dando erro de compilação, tirando qualquer um dos construtores funcionara.

T

eu tbm acho… essa é complicada!

P

O problema acontece pq vc está colocando parâmetros diferentes para chamar o mesmo método. O 1º parâmetro é um Wrapper Long e o 2º é um primitivo long, aí está o problema. Não tem nenhum construtor que receba como argumento um Wrapper Long e um primitivo long. Ou vc sobrecarrega outro construtor que tenha como argumento um Wrapper Long e um primitivo long ou na hora de chamar o construtor passe como está definido nos construtores…blz!!!

vlw

T

O compilador disse:

anderson.bonavides

Erro de compilação na linha 15. Se vc mudar a variável Long na linha 14 para long o código compilará e imprimirá long a, long b.

Raff

essa foi chata em :slight_smile: mas da erro de compilação mesmo !

Raff
mas o que vocês acham desse código aqui olha
public class TesteGuj{


public static void go(int[] a){
System.out.println("Estou em array");

}

public static void go(int... a){

System.out.println("estou em vararg");
}

public static void main(String... a){

go(1,2,3);//qual o resultado ????

}
}
victorwss

Essa é fácil. Dá erro de compilação porque … e [] são equivalentes (that’s just synthatic sugar), daí teria dois métodos com a mesma assinatura.

[Edit: hmm pensando bem, acho que estou enganado. Acho que ele chamaria o varargs.]

Raff

exatamente :slight_smile:

vanzella

thingol:
O compilador disse:

javac:

Locura.java:15: reference to Locura is ambiguous, both method Locura(java.lang.Long,java.lang.Long) in Locura and method Locura(long,long) in Locura match
new Locura(a, 15L);
^
1 error

hehe, foi dai mesmo que tirei minhas conclusões;

essa tbm é boa;

public class Teste {
	public Teste(Object obj) {
		System.out.println("Object");
    }
    public Teste(String obj) {
    	System.out.println("String");
    }
    public Teste(Integer obj) {
    	System.out.println("Integer");
    }
    public static void main(String[] args) {
    	new Teste(null);
    }
}

e essa:

public class Teste {
    public Teste(Object obj) {
    System.out.println("Object");
    }
    public Teste(A obj) {
    System.out.println("A");
    }
    public Teste(B obj) {
    System.out.println("B");
    }
    public static void main(String[] args) {
    new Teste(null);
    }
    class A {
    }
    class B extends A {
    }
}
Raff

O primeiro não compila é ambigu :slight_smile:

Raff

e a segunda pega o tipo mais generico possivel ou seja imprimi B

anderson.bonavides

Galera quero vem quem mata essa aki sem compilar. Pegando a carona no código do nosso amigo. Eu digo a resposta mas vamos ver o que todos dizem.

public class Teste2{ public Teste2(Object obj) { System.out.println("Object"); } public Teste2(A obj) { System.out.println("A"); } public Teste2(B obj) { System.out.println("B"); } public Teste2(C obj) { System.out.println("C"); } public Teste2(A2 obj) { System.out.println("A2"); } public static void main(String[] args) { new Teste2(10); C c1 = null; c1.Teste2(new A2(){public void Teste2(A a) {}}) } class A { } class B extends A { } public class C implements A2{ public void Teste2(A2 a){} public void Teste2(A a) {} } interface A2{void Teste2(A a);} }

Respostas:
a)Imprime A2
b)Imprime C
c)Lança uma exceção em tempo de execução
d)Contêm um erro em um ponto do código
e)Contêm varios erros
f)Imprime B
g)Imprime A

vanzella

c) Lança uma exceção em tempo de execução, na linha 20.

anderson.bonavides

Alguêm mais?

anderson.bonavides

anderson.bonavides:
Galera quero vem quem mata essa aki sem compilar. Pegando a carona no código do nosso amigo. Eu digo a resposta mas vamos ver o que todos dizem.

public class Teste2{ public Teste2(Object obj) { System.out.println("Object"); } public Teste2(A obj) { System.out.println("A"); } public Teste2(B obj) { System.out.println("B"); } public Teste2(C obj) { System.out.println("C"); } public Teste2(A2 obj) { System.out.println("A2"); } public static void main(String[] args) { new Teste2(10); C c1 = null; c1.Teste2(new A2(){public void Teste2(A a) {}}) } class A { } class B extends A { } public class C implements A2{ public void Teste2(A2 a){} public void Teste2(A a) {} } interface A2{void Teste2(A a);} }

Respostas:
a)Imprime A2
b)Imprime C
c)Lança uma exceção em tempo de execução
d)Contêm um erro em um ponto do código
e)Contêm varios erros
f)Imprime B
g)Imprime A

Chegou perto vanzella. Olha só ocorre um erro de compilação. Se vc prestar atenção na linha da chamada do método vai verificar que estã faltando um ponto e virgula no final da classe de método.
Olha só a identação:

c1.Teste2(new A2(){ public void Teste2(A a) { } }); //faltava o ponto e virgula.

Caso corrigisse esse problema ai sim o código lançava uma exceção como vc destacou.
Fiz isso pra testar pra ver se a turma tava compilando o código antes de postar a saída. Mas nem deu tempo.

:wink:

F

boa essa pegadinha anderson :-o

vanzella

putz, é mesmo, não percebi, nem analisei mais o código depois que vi uma chamada de um objeto nulo.

B

Não compila na linha 10, pq não tem nenhum construtor que receba int. É isso?

LPJava

eu tb concordo procurei e nao vi nenhum construtor com int… o codigo nao compila!! nesse caso seria letra D ou letra E, pois nao olhei todo o codigo… entao a letra E tb pode ser verdadeira… hehe!

anderson.bonavides

Mas tem um que recebe um Object. O erro real é da linha 20 na classe interna faltando o ;

B

Mas um tipo primitivo vai se encaixar num Object?

Quanto à linha 20 vc tem razão, eu não prestei atenção.

Etnão pra mim a resposta é e)Contêm varios erros

anderson.bonavides

bruceramone:
Mas um tipo primitivo vai se encaixar num Object?

Quanto à linha 20 vc tem razão, eu não prestei atenção.

Etnão pra mim a resposta é e)Contêm varios erros

Faz assim então. Compila pa vc verificar se tem mais de um? Caso vc corriga esse erro q te falei vc vai ver a exceção rolando.

LPJava

Object != int sao tipos diferentes… :smiley:

E isso faz maior diferença na assinatura…

class Dif{
static void metd(Object a){
System.out.println("object");
}

public static void main(String[]a){
metd(10);
}

me diz o resultado…

Raff

Object… isso LPJava

anderson.bonavides

A desculpa realmente um int não pode receber um Object. Caso não lançase a exceção a saída seria C. Realmente eu concordo até pq não é possivel fazer converter para Integer e depois passar para Object. Mas a verdade é que o código compila sim. Comente as linhas 19 e 20 então verá o real resultado.

anderson.bonavides

É teu código ta compilando e ta imprimindo OBJECT. Isso quer dizer tbm que falei bobagem na minha tentativa de explicação anterior. :shock:

B

Aqui não compila de jeito nenhum, nem o código do LPJava.

Estamos ficando doidos? :lol:

vanzella

bruceramone:
Aqui não compila de jeito nenhum, nem o código do LPJava.

Estamos ficando doidos? :lol:

Ta usando java 1.5?
Compila sim.
Na teoria o compilador faz autobox de int pra Integer, sendo assim temos um metodo que recebe um Object, como quase todas as classes extendem object funciona.

Tanto é que se você colocar assim:

static void metd(Number a){  
    System.out.println("Number ");  
    }

A chamada sera pra Namber pois Number é um nivel mais baixo de hierarquia, comparado com Object.

B

Tô usando o Java 1.4, é isso.

LPJava

bruceramone:
Aqui não compila de jeito nenhum, nem o código do LPJava.

Estamos ficando doidos? :lol:

se compilasse estariamos ficando doido heheheh !! ainda bem que nao compila… :smiley:

vc entendeu o intuito do meu codigo…?

vanzella

LPJava:
bruceramone:
Aqui não compila de jeito nenhum, nem o código do LPJava.

Estamos ficando doidos? :lol:

se compilasse estariamos ficando doido heheheh !! ainda bem que nao compila… :smiley:

vc entendeu o intuito do meu codigo…?

Eu não entendi, estamos falando de autobox, autobox somente java 1.5 e acima.

LPJava

vanzella:
LPJava:
bruceramone:
Aqui não compila de jeito nenhum, nem o código do LPJava.

Estamos ficando doidos? :lol:

se compilasse estariamos ficando doido heheheh !! ainda bem que nao compila… :smiley:

vc entendeu o intuito do meu codigo…?

Eu não entendi, estamos falando de autobox, autobox somente java 1.5 e acima.

o intituito do meu codigo foi provar que o autobox nao funciona… de int para Object… e tinha um erro naquele codigo onde o construtor… chama Teste2(10) sendo q nao existe um construtor com essa assinatura…

vanzella

Tudo bem não existe autobox diretamente de int pra Object, mas o codigo compila sem erros, o compilador faz autobox de int para Integer e depois a conversão de tipos, como Integer extende Object, funciona.

LPJava

vanzella:
LPJava:

o intituito do meu codigo foi provar que o autobox nao funciona… de int para Object… e tinha um erro naquele codigo onde o construtor… chama Teste2(10) sendo q nao existe um construtor com essa assinatura…

Tudo bem não existe autobox diretamente de int pra Object, mas o codigo compila sem erros, o compilador faz autobox de int para Integer e depois a conversão de tipos, como Integer extende Object, funciona.

isso que quis dizer diretamente nao n dar para fazer de int para Object… porem eu posso fazer o q vc falou :smiley:

vanzella

LPJava:

isso que quis dizer diretamente nao n dar para fazer de int para Object… porem eu posso fazer o q vc falou :D

Mas então compila? :smiley: rsrs.
Abraço…

anderson.bonavides

Cara olha só o que eu acho.

Object é a superclasse de todas. Number extende de Object e Integer, Double, Float, String, Char, Long, Short são todas irmas.
Vc pode converter para um pai que no mas não da para converter para um irmão na hierarquia. Axo que esse é o grande motivo para se conseguir converter para um Number e um Object sem dar erro de compilação. Mas não da pra converter um Integer para um Long nem um Duble para um Float mas para um Number ou Object da sim.

vanzella

anderson.bonavides:
Cara olha só o que eu acho.

Object é a superclasse de todas. Number extende de Object e Integer, Double, Float, String, Char, Long, Short são todas irmas.
Vc pode converter para um pai que no mas não da para converter para um irmão na hierarquia. Axo que esse é o grande motivo para se conseguir converter para um Number e um Object sem dar erro de compilação. Mas não da pra converter um Integer para um Long nem um Duble para um Float mas para um Number ou Object da sim.

É isso ai velho, conversão das irmas :lol: , somente se forem primitivos, tipo short pra int, float pra double …

Sami_Koivu

LPJava:
o intituito do meu codigo foi provar que o autobox nao funciona… de int para Object… e tinha um erro naquele codigo onde o construtor… chama Teste2(10) sendo q nao existe um construtor com essa assinatura…

Você acabou provando exatamente o oposto. Chegou a tentar compilar seu próprio código com Java 1.5?

Funciona. Compila. Não há erro.

Criado 23 de janeiro de 2008
Ultima resposta 24 de jan. de 2008
Respostas 40
Participantes 11