Ambiguidade no JDK 1.4

12 respostas
R

Fala turma…

fiz meu sistema no jdk 1.3 e tudo certo…ai fui compila-lo no 1.4 e apareceu o seguinte erro:

frmConAtividade.java:2172: reference to compareTo is ambiguous, both method compareTo(java.util.Date) in java.util.Date and method compareTo(java.lang.Object) in java.sql.Timestamp match

como resolver essa ambiguidade gerada, q nao aparecia no 1.3??

valew

12 Respostas

Elvis.The.Pelvis
Timestamp t = new Timestamp(0);
Date d = new Date(0);
t.compareTo(d);
Analisando a classe Timestamp:

1 - Ela é filha de java.util.Date

2 - Por ser filha, ela herda int compareTo(Date d)

3 - A classe Timestamp agora tem três métodos compareTo:

int compareTo(Object o)

int compareTo(Date d) //vem a partir de herança

int compareTo(Timestamp ts)

Quando você faz:

t.compareTo(d);

O java não sabe se você quer chamar compareTo(Object) ou compareTo(Date)(herdada). Se compareTo(Date) fosse declarada explicitamente na classe Timestamp (ou se compareTo(Object) não fosse declarada e herdada também), não teria problemas.

Para resolver, use: (OOOOOPs se fizer isso dá ClassCastException)

t.compareTo((Object)d);

Pois você chamará o método que aceita um Object como parâmetro, mas lançará ClassCastException

Faça então o inverso:

d.compareTo(t);

Isso é inédito para mim. Não sei por que o Java trata métodos herdados diferentemente dos métodos overriden. Descobri fuçando as classes e fazendo testes.

Alguém tem alguma idéia do por que disso.[/code]

Elvis.The.Pelvis

No caso

interface F{
}

class A {
  public void dodo(A a) {
  }

  public void dodo(I i) {
  }
}

class B extends A implements F {
}

Algo do tipo:

A a = new A();
  B b = new B();
  a.dodo(b);

É até lógico que de erro, pois “b” tanto é filha de A (caindo no método dodo(a)) quanto implementa a interface I (caindo no método dodo(I)).

Agora no caso de Timestamp e Date, me surpreendeu realmente saber que os métodos que são herdados dão ambiguidade se não forem overriden explicitamente.

Já que “t.compareTo(d)” tenta se comparar com um objeto do tipo Date e o método compareTo(Date) existe, mesmo que vindo por herança, na minha cabeça teria que funcionar e não dar ambiguidade com compareTo(Object)

Bani

Realmente estranho isso. Eu lembro que em uma palestra no TechDays foi dito que quando houvesse ambiguidade sobre qual método chamar (por exemplo, mandando null para um método overloaded que aceitaria vários tipos de objetos), o Java escolheria automaticamente o que fosse mais específica.
E agora também fiz meu próprio teste de métodos herdados e vi que realmente dá problema.

Paulo_Silveira

creio que nem um, nem outro pessoal

APOSTO que voce esta passando NULL como argumento

this.compareTo(null)

posta a linha ai que da a ambiguidade
outra coisa, NUNCA escreva uma classe q tem esse numero enorme de linhas

Bani

A ambiguidade realmente existe. Veja esse exemplo:

public class Teste {

public static void main(String[] args) {

TesteFilho teste = new TesteFilho();

String t = t;

teste.teste(t);

}

}
class TestePai {

public void teste(String teste) {

System.out.println(TestePai);

}

}
class TesteFilho extends TestePai {

public void teste(Object teste) {

System.out.println(TesteFilho);

}

}

Nesse caso, ao compilar dá a mensagem:
C:>javac Teste.java
Teste.java:6: reference to teste is ambiguous, both method teste(java.lang.String) in TestePai and method teste(java.lang.Object) in TesteFilho match
teste.teste(t);
^
1 error

Se fizer exatamente a mesma coisa colocando os dois métodos na classe pai, ele compila normalmente.

Paulo_Silveira

eh o virtual method lookup do java… confusao… decidir qual dos overloadeds q ele vai usar deveria ser facilimo

e o mais engracado, esse codigo que a bani colocou, se voce inerter o metodo do pai com o filho, tambem compila. Isto eh, poe o obvject no pai, e o String no filho.

R

valeu pelas dicas pessoal…

resolvi o problema da ambiguidade fazendo um simples casting…

Timestamp.compareTo((Object)Date)

ai deu certo…

o estranho eh q no 1.3 tb tem essa heranca, mas nao dah erro algum…

falow

Elvis.The.Pelvis

No chutômetro…

Uma classe filha possui
facaAlgo(Object)
facaAlgo(TipoPai) //essa vem da heranca

Quando a filha chama
facaAlgo(new TipoPai());
O Java sabe que ela se encaixa tanto em Object quanto em TipoPai. Só que como facaAlgo(TipoPai) é herdada e nãofoi declarada explicitamente o Java pode pensar.

“Essa chamada pode ser atendida pelos dois métodos. O correto é o método facaAlgo(TipoPai). Só que como ela veio através de herança, o sujeito pode não saber que ele existe e pensar que eu vou chamar facaAlgo(Object). Vou lançar uma exceção de ambiguidade para que ele tenha certeza do que ele está fazendo.”

Será que é isso ou é alguma coisa que os desenvolcedores da linguagem deixaram passar desapercebido?

dukejeffrie

Elvis, vc me fez lembrar de um problema idiota que eu tive há bastante tempo, com o método equals.

Tinha uma bosta de um equals herdado de object, que ele chamava sem eu querer. Se é essa a razão do erro, então achei ótimo aparecer isso.

Mas que eu saiba, o method lookup procura métodos na seguinte ordem:

  1. métodos com argumento do mesmo tipo do parâmetro na classe to objeto (i.e, sem cast)
  2. métodos com argumento de um supertipo do parâmetro na classe do objeco (i.e, upcast);
  3. 1, 2 e 3 para a superclasse, se houver.

até não ter mais onde procurar.

Alguém que tá fazendo certificação e aprendeu direito isso pode explicar?? : ))

G

Pessoal! :smiley:
Estou com o mesmo problema do colega acima. E, mesmo com as dicas aqui não consegui resolver.
Será que alguém pode me ajudar?!?

The method compareTo(Date) in the type Date is not applicable for the arguments (Object)

238: 	int compare;

239: 	if(!Feriados.isEmpty()){

240: 		for(int x = 0; x < Feriados.size(); x++){

241: 			compare = data.compareTo(Feriados.get(x));

242: 			if(compare == 0){

243: 				Retorno = true;

244: 				break;

minha classe:

private boolean EFeriado( Vector Feriados, java.util.Date data){

boolean Retorno = false;

int compare;

if(!Feriados.isEmpty()){

for(int x = 0; x < Feriados.size(); x++){

compare = data.compareTo(Feriados.get(x));

if(compare == 0){

Retorno = true;

break;

}else if(compare < 0){

break;

}

}

}

return Retorno;

}
S

Cara, na verdade vc só precisa fazer um cast.

G

então …

quando eu faço o cast dessa forma, aí sim, dá erro de ambiguidade.

-The type date is ambiguous

Criado 10 de fevereiro de 2003
Ultima resposta 11 de jun. de 2008
Respostas 12
Participantes 7