In che modo viene risolta l’ambiguità nella scelta di metodi sovraccaricati in Java?

package org.study.algos; public class Study { public static void main(String[] args) { A a = new A(); a.m1(null); } } class A { public void m1(String s) { System.out.println("String"); System.out.println(s); } public void m1(Object obj) { System.out.println("Object"); System.out.println(obj); } } 

Qui, l’output è

String null

Perché la JVM risolve il metodo con uno con un argomento String?

Grazie in anticipo J

È un algoritmo abbastanza elaborato, dettagliato in JLS 15.12 . Ma la parte che è rilevante qui è 15.12.2 , che dice “viene scelto il più specifico”. Entrambi gli overload di Object e String sono “accessibili e applicabili” (la stringa è applicabile perché un valore letterale nulla è un riferimento di tutti i tipi) e la stringa è più specifica.

EDIT: sezione corretta, per sintattica.

Questi metodi sono “sovraccarichi”, non “ambigui”.

Secondo la specifica del linguaggio Java :

Quando viene invocato un metodo (§15.12), il numero di argomenti effettivi (e qualsiasi argomento di tipo esplicito) e i tipi di tempo di compilazione degli argomenti vengono utilizzati, in fase di compilazione, per determinare la firma del metodo che verrà richiamato ( §15.12.2).

E il § 15.12.2 dice:

Ci possono essere più di un metodo di questo tipo, nel qual caso viene scelto quello più specifico .

String è più specifica di Object , quindi mentre null è compatibile con entrambi, viene scelto il metodo con il parametro String (esistono regole molto più complesse che si applicano quando i tipi di parametri fanno parte di una class o di una gerarchia di interfacce).

il valore nullo può essere impostato come riferimento di qualsiasi tipo. Tutti i metodi sovraccaricati che hai sono in una gerarchia di eredità Object <- String, viene scelto quello meno generale. Ma se avessi due metodi sovraccaricati che non sono nella stessa gerarchia, allora otterrai un errore di compilazione sui metodi ambigui.

Una stringa è un object, un object non è una stringa, quindi il primo sovraccarico è più specifico del secondo. Vedi JLS 15.12.2 , come sintattico menzionato.

Ho fatto una domanda simile. Jon Skeet ha scritto una grande risposta.

Il link alla mia domanda: quale sovraccarico verrà selezionato per null in Java?