Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

454
Views
¿Por qué recibo un error de ambigüedad en este código?

Digamos que tenemos estas 3 clases:

 class A { } class B extends A { } public class App { static void f(int i, A a) { } static void f(float j, B b) { } static public void main() { int i = 0; B b = new B(); App.f(i, b); } }

Esto produce el error:

 App.java:11: error: reference to f is ambiguous App.f(i, b); ^ both method f(int,A) in App and method f(float,B) in App match 1 error

¿Por qué no elige el tipo f(int, A) ya que i es un número entero?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Es ambiguo por dos razones:

  • ambas sobrecargas son aplicables , y;
  • ninguna sobrecarga es más específica que la otra

Tenga en cuenta que tanto la sobrecarga f(int, A) como la sobrecarga f(float, B) se pueden llamar con los parámetros (i, b) , ya que hay una conversión implícita de int a float y una conversión implícita de B a A

¿Qué sucede cuando hay más de un método aplicable? Se supone que Java debe elegir el método más específico. Esto se describe en §15.12.2.5 de la especificación de idioma. Resulta que no se da el caso de que una de estas sobrecargas sea más específica que la otra.

Un método aplicable m1 es más específico que otro método aplicable m2, para una invocación con expresiones de argumento e1, ..., ek, si cualquiera de los siguientes es verdadero:

  • m2 es genérico [...]

  • m2 no es genérico, y m1 y m2 son aplicables por invocación estricta o flexible, y donde m1 tiene tipos de parámetros formales S1, ..., Sn y m2 tiene tipos de parámetros formales T1, ..., Tn, el tipo Si es más específico que Ti para el argumento ei para todo i (1 ≤ i ≤ n, n = k).

  • m2 no es genérico, y m1 y m2 son aplicables por invocación de aridad variable [...]

Solo el segundo punto se aplica a las dos sobrecargas de f . Para que una de las sobrecargas sea más específica que la otra, cada tipo de parámetro de una sobrecarga debe ser más específico que el tipo de parámetro correspondiente en la otra sobrecarga.

Un tipo S es más específico que un tipo T para cualquier expresión si S <: T ( §4.10 ).

Tenga en cuenta que "<:" es la relación de subtipificación. B es claramente un subtipo de A float es en realidad un supertipo (¡no un subtipo!) de int . Esto se puede derivar de las relaciones directas de subtipificación enumeradas en§4.10.1 . Por lo tanto, ninguna de las sobrecargas es más específica que la otra.

La especificación del idioma continúa hablando sobre métodos específicos máximos , lo que realmente no se aplica a f aquí. Finalmente, dice:

De lo contrario, la invocación del método es ambigua y se produce un error en tiempo de compilación.

Más ejemplos

 static void f(int x) {} static void f(float x) {}

cuando se les llama con un int no son ambiguos porque la sobrecarga de int es más específica.

 static void f(int x, B a) {} static void f(float x, A a) {}

cuando se les llama con tipos de argumentos (int, A) no son ambiguos porque la sobrecarga (int, B) es más específica.

 static void f(int x, A a) {} static void f(float x, A a) {}

cuando se llama con tipos de argumento (int, A) no son ambiguos porque la sobrecarga (int, A) es más específica. Tenga en cuenta que la relación de subtipificación es reflexiva (es decir, A es un subtipo de A ).

over 4 years ago · Santiago Trujillo Report

0

Dos cosas:

  • Tipo de ensanchamiento (1er parámetro)
  • Herencia (segundo parámetro)

Ampliación de tipo : float es un tipo "más ancho" que int , por lo tanto, el valor de int pasado se puede empaquetar fácilmente en una caja float más grande. No funcionará en caso de que nos gustaría "empaquetar" float en int , ya que potencialmente podemos perder el punto flotante. En el caso previsto, al tener un int , potencialmente podemos pasarle dos funciones.

 fFloat(float f){} int intValue = 221; fFloat(intValue); // inside f, intValue is treated as 221.0 fInt(int i){} float floatVal = 221.221; fInt(floatVal); // what should compiler do with remaining .221 part?

Herencia : A es una clase base, mientras que B es una de las subclases de A. Entonces, cuando declaramos el parámetro del método como una clase base, podemos proporcionar allí tanto la clase base como su instancia (pero podremos usar B b instancia dentro f(int i, A a) como tipo A Por lo tanto, podemos pasar B b = new B(); a ambos métodos también.

 class A { public void f() {} } class B extends A { public void g() {} } fA(A a){} B bInst = new B(); fA(bInst); // you can refer only to f() method, not g() fB(B b){} A aInst = new A(); fB(aInst); // you cannot do this, as subclass can have some additional // stuff, that superclass does not have //but even A aInstBImpl = new B(); fB(aInstBImpl); // will not work without explicit casting as it is // kind of A instance with B implementation - here polymorphism comes into action

Dado que los 2 parámetros (de 2 posibles) pueden adaptarse a ambos métodos sin ninguna "acción tomada" explícita, surge el error de ambigüedad.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!