๐ŸŽ“ A1Learner
๐Ÿ”
0 of 30 lessons completed

Java Bridge Methods

A bridge method is an extra method the compiler writes into a class file. It appears when a class implements a generic interface with one fixed type.

One method in source, two in the class file

TextBox writes one compareTo method. Reflection lists the declared methods in sorted order.

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    List<String> rows = new ArrayList<>();
    for (Method method : TextBox.class.getDeclaredMethods()) {
      rows.add(method.getName() + " bridge=" + method.isBridge());
    }
    Collections.sort(rows);
    for (String row : rows) {
      System.out.println(row);
    }
  }
}
class TextBox implements Comparable<TextBox> {
  private final String text;
  TextBox(String text) {
    this.text = text;
  }
  public int compareTo(TextBox other) {
    return this.text.compareTo(other.text);
  }
}

The bridge cast refuses the wrong type

A raw Comparable call passes an Integer. The bridge cast fails at runtime.

public class Main {
  public static void main(String[] args) {
    Comparable raw = new TextBox("apple");
    System.out.println(raw.compareTo(Integer.valueOf(5)));
  }
}
class TextBox implements Comparable<TextBox> {
  private final String text;
  TextBox(String text) {
    this.text = text;
  }
  public int compareTo(TextBox other) {
    return this.text.compareTo(other.text);
  }
}

Sorting runs through the typed method

A list of TextBox values sorts by the typed compareTo. The sorted order prints in full.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    List<TextBox> boxes = new ArrayList<>();
    boxes.add(new TextBox("pear"));
    boxes.add(new TextBox("apple"));
    boxes.add(new TextBox("kiwi"));
    Collections.sort(boxes);
    for (TextBox box : boxes) {
      System.out.println(box.text());
    }
  }
}
class TextBox implements Comparable<TextBox> {
  private final String text;
  TextBox(String text) {
    this.text = text;
  }
  String text() {
    return this.text;
  }
  public int compareTo(TextBox other) {
    return this.text.compareTo(other.text);
  }
}

Example

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    List<TextBox> boxes = new ArrayList<>();
    boxes.add(new TextBox("pear"));
    boxes.add(new TextBox("apple"));
    boxes.add(new TextBox("kiwi"));
    Collections.sort(boxes);
    for (TextBox box : boxes) {
      System.out.println(box.text());
    }
    int count = 0;
    for (Method method : TextBox.class.getDeclaredMethods()) {
      if (method.getName().equals("compareTo")) {
        count++;
      }
    }
    System.out.println("compareTo methods: " + count);
  }
}
class TextBox implements Comparable<TextBox> {
  private final String text;
  TextBox(String text) {
    this.text = text;
  }
  String text() {
    return this.text;
  }
  public int compareTo(TextBox other) {
    return this.text.compareTo(other.text);
  }
}

Key points

  • Type erasure is the removal of generic type details at compile time.
  • Erasure leaves one compareTo slot that takes an Object in the class file.
  • The bridge method matches that erased slot and takes an Object.
  • The bridge casts its argument to the fixed type and delegates to the typed method.
  • Source code holds one compareTo method, and the class file holds two.
  • Reflection lists both methods, and isBridge marks the compiler-written one.

In this example, the boxes print in sorted order through the typed compareTo, and the count of compareTo methods in the class file is two.

Note

Covariant return types grow bridge methods the same way.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Why does TextBox hold two compareTo methods in its class file?