Элегантный способ изменить тип (класса-) экземпляра в байт-коде Java

В течение некоторого времени я работал над решением следующей проблемы. Допустим, у меня есть следующий код Java:

public class A {
  public void start() {
    List l = new ArrayList();
    l.add("abc");
    System.out.println( l.get(0) );
  }
}

Результатом компиляции этого кода является файл класса A.class, содержащий байт-код Java. Я написал ClassLoader, который загружает A.class и выполняет start(), Мое намерение заменить в загруженном A.class (байт-код) new ArrayList() с MyArrayList():

//Before
List l = new ArrayList();
//After
List l = new MyArrayList();

Класс MyArrayList определяется аналогично: class MyArrayList extends ArrayList

1 ответ

Решение

Вы можете использовать такой инструмент, как ASM, чтобы проанализировать файл и заменить возникновение любого ArrayList с MyArrayList, Это, однако, потребует, чтобы MyArrayList определяет конструкторы с идентичной сигнатурой для конструкторов, определенных в ArraysList,

Следующий вопрос - когда вы определяете изменения. У вас есть следующие возможности:

  1. Измените реализацию во время сборки: вы можете написать плагин для инструмента сборки, который будет применять ваши преобразования.
  2. Измените реализацию во время выполнения, используя агент Java: API Attach позволяет вам изменять загруженный класс даже во время выполнения.
  3. Измените реализацию до первой загрузки класса: вы можете использовать загрузчик пользовательских классов для загрузки вашего измененного класса. Это должно произойти до того, как класс будет загружен регулярно!
Другие вопросы по тегам