Il Late Binding in Java – Lezione 7 di Java Avanzato

Individuare la firma di un metodo nel Late Binding

All’inizio del Late Binding la JVM riceve la firma più specifica, ovvero riceve solo il nome di un metodo e il tipo dei suoi paramentri. Dato che a tempo di esecuzione potrebbero esserci un overriding dei metodi, bisogna cercare il vero e proprio metodo concreto invocato. Il Late Binding si occupa proprio di questo, individua il metodo vero e proprio che dovrà essere invocato. Il metodo cercato sicuramente è presente in una classe, se non vi fosse avremmo avuto un errore a tempo di compilazione e a runtime non ci saremmo mai artivati.

A partire dalla classe effettiva dell’oggetto che ha invocato il metodo, risaliamo nelle superclasse e non appena troviamo un metodo esattamente uguale a quello cercato ci fermiamo e lo invochiamo. Si cerca il primo metodo con la stessa firma a partire dalla classe effettiva (siamo a runtime) della variabile con cui si è invocato il metodo, se il metodo non viene trovato nella classe effettiva della variabile si risale nelle superclassi fino a trovarlo (nel caso peggiore arriveremo fino ad Object).

Calcolare le firme candidate e il loro l’overriding

Facciamo un esempio in cui per semplicità indicheremo una firma di un metodo racchiudendo i tipi dei parametri tra due parentesi. Dato il seguente programma:

  class A {
    private int f() { return 1; }
    public int f(int x) { return f() + 1; }
  }

  class B extends A {
    public int f(boolean x ) { return 3; }
    public int f(double x ) { return f(true) + 1; }
    public int f(int x, double y) { return 3; }
    public int f(double x, int y) { return 7; }
  }

  class C extends B {
    public int f(boolean x ) { return 5; }
    public int f(int x ) { return 6; }
  }

  public class Test {
    public static void main(String[ ] args) {
      B beta = new C();
      System.out.println(beta.f(1));
      System.out.println(beta.f(2, 1));
    }
  }

Per la chiamata al metodo beta.f(1):
Early Binding. Fase 1: partiamo dal tipo dichiarato della variabile beta, quindi dalla classe B, e cerchiamo da questa classe a salire tutte le firme compatibili con la firma (int) chiedendoci se int è compatibile con la firma dei metodi incontrati. In B troviamo la firma (boolean) che non risulta compatibile e la firma (double) che risulta compatibile, infine anche le firme (int, double) e (double, int) non sono compatibili. In A avremo che la firma senza argomenti () non può essere utilizzata, al contrario la firma (int) risulta compatibile, infine in Object non troviamo nessun’altra firma compatibile. La tabella delle firme candidate conterrà solo due firme: (double) e (int).

Fase 2: dobbiamo individuare la firma più specifica tra tutte le firme candidati, ed avremo che la firma (int) risulta essere la firma più specifica.

Late Binding. Abbiamo in ingresso la firma (int) e a partire dal tipo effettivo della variabile beta, quindi dalla classe C (perché B beta = new C();), cerchiamo il primo metodo con esattamente la stessa firma di quella cercata. Il primo metodo individuato con firma (int) si trova in C e il risultato che verrà stampato sullo schermo sarà il numero 6.

Avremo che per la chiamata al metodo beta.f(2, 1):

Early Binding. Fase 1: partiamo dal tipo dichiarato della variabile beta, quindi dalla classe B, e cerchiamo da questa classe a salire tutte le firme compatibili con la firma (int, int) chiedendoci se int e int risultano compatibili con la firma dei metodi incontrati. In B avremo che la firma (boolean) e (double) non possono essere candidate, invece la firma (int, double) risulta compatibile perché int può essere assegnato ad int e il secondo int può essere assegnato a double. Al contrario anche la firma (double, int) risulterà compatibile con la firma cercata. In A ed in Object non troviamo nessun’altra firma compatibile con quella cercata.
La tabella delle firme candidate per la chiamata beta.f(2, 1) saranno: (int, double) e (double, int).

Fase 2: dobbiamo individuare la firma più specifica tra tutte le firme candidate, purtroppo nessuna firma risulta essere più specifica di un altra perché se da un verso la prima firma ha il primo parametro più specifico, la seconda ha il secondo parametro più specifico. Avremo un errore a tempo di compilazione per ambiguità (non possiamo decidere qual è la firma più specifica). Se avessimo disegnato un grafo (utile soprattutto con molti metodi) avremmo disegnato un arco tratteggiato tra le due firme.

Indice Lezione PrecedenteLezione Successiva

Nota: l’esempio finale è basato sulla prova intercorso del 27 Aprile 2006 del professor Marco Faella.

Pubblicato in Guide, Java, Programmazione Taggato con: , , , , ,
One comment on “Il Late Binding in Java – Lezione 7 di Java Avanzato
  1. marco scrive:

    Grazie mille, mi è stato molto utile! Vorrei chiedere però una precisazione sulla firma dei metodi: come incide il tipo di ritorno dei metodi sull’early binding e soprattutto sul late binding (in particolare per quel che riguarda il ritorno covariante nell’overriding e quindi nella scelta del metodo).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*