Перемещение финальных классов в другой пакет без нарушения бинарной совместимости - PullRequest
1 голос
/ 12 марта 2020

Итак, у меня есть одноэлементный класс final и Serializable, представленный как часть publi c API моей библиотеки, и я хочу перейти в другой пакет, надеюсь, без нарушения бинарной совместимости. Моя установка выглядит примерно так:

package a;

public final class MyApi implements Serializable {
  private static final long serialVersionUid = 1L;
  private static final MyApi instance = new MyApi();

  public static MyApi getInstance() { return instance; }

  private MyApi() {}

  private Object readResolve() { return instance; }
}

Чтобы переместить ее в другой пакет, я удалил модификатор final из класса и сделал его основной конструктор public c. Затем в своем новом пакете я расширил этот класс и перенаправил все поля stati c в исходном классе на новый экземпляр. И в качестве последнего шага я сделал оригинальный конструктор throw, если этот класс не является экземпляром нового класса (это часть, в которой я в основном не уверен):

package a;

@Deprecated
public class MyApi implements Serializable {
  private static final long serialVersionUid = 1L;

  public static MyApi getInstance() {
    return b.MyApi.getInstance();
  }

  public MyApi() {
    if (!getClass().equals(b.MyApi.class) {
      throw new AccessControlException("Historical alias. Extension is prohibited.") 
    }
  }

  private Object readResolve() {
    return b.MyApi.getInstance()
  }
}

package b;

public final class MyApi extends a.MyApi {
  private static final long serialVersionUid = 1L;
  private static final MyApi instance = new MyApi();

  public static MyApi getInstance() { return instance; }

  private MyApi() {}

  private Object readResolve() { return instance; }
}

Мой вопрос к вам это: вы думаете, это разумный подход? Это на самом деле двоичная совместимость или есть что-то в этой настройке, которая не будет совместима? Есть ли способ сделать его лучше?

...