Итак, у меня есть одноэлементный класс 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; }
}
Мой вопрос к вам это: вы думаете, это разумный подход? Это на самом деле двоичная совместимость или есть что-то в этой настройке, которая не будет совместима? Есть ли способ сделать его лучше?