Абстрактная константа в Java
Я хотел бы создать константу, не реализованную в суперклассе, чтобы заставить подклассы реализовать ее. Лучшее решение, которое я нашел (по этой теме) - создать абстрактный метод, который будет возвращать постоянное значение. Я предполагаю, что невозможно сделать что-то вроде:
abstract final static String Name;
Но у меня все еще есть надежда, потому что Java использует что-то подобное в Serializable интерфейсе с serialVersionUID. Кто-то знал, как они это сделали? Можно ли воспроизвести это в моем собственном классе?
Ответы
Ответ 1
Наличие поля serialVersionUID
не обеспечивается интерфейсом Serializable
поскольку интерфейс не может обеспечить наличие поля. Вы можете объявить класс, который реализует Serializable
, он будет прекрасно компилироваться без serialVersionUID
поля serialVersionUID
.
Проверка поля serialVersionUID
жестко задана в инструментах. Одним из примеров является JDK java.io.ObjectStreamClass.getSerialVersionUID()
который загружает значение serialVersionUID
с отражением:
/**
* Returns explicit serial version UID value declared by given class, or
* null if none.
*/
private static Long getDeclaredSUID(Class<?> cl) {
try {
Field f = cl.getDeclaredField("serialVersionUID");
int mask = Modifier.STATIC | Modifier.FINAL;
if ((f.getModifiers() & mask) == mask) {
f.setAccessible(true);
return Long.valueOf(f.getLong(null));
}
} catch (Exception ex) {
}
return null;
}
Ответ 2
Такая константа не может быть static
поскольку static
поля являются общими для всех экземпляров класса, включая экземпляры всех подклассов. Вот как реализовать это как нестатическую константу:
public abstract class Foo {
public final String name; // Particular value to be defined in subclass
protected Foo (String name) {
this.name = name;
}
}
public class Bar extends Foo {
public Bar () {
super ("Zoo"); // Here we define particular value for the constant
}
}
Кстати, serialVersionUID
не является частью интерфейса Serializable
.
Ответ 3
Я бы не рекомендовал это, но если вам это так нужно, вы можете создать проверку регулярных выражений в Checkstyle и заставить людей реализовать статическую переменную
Ответ 4
Когда класс, реализующий Serializable
, не имеет serialVersionUID
небольшое сообщение, которое вы видите в вашей IDE и во время компиляции, является предупреждением, javac
. Если вы хотите создать что-то подобное, вы можете, но процесс кажется сложным. Решение здесь в этом ответе.
Они углубляются в детали, но общая идея состоит в том, чтобы создать процессор аннотаций и аннотаций и использовать процессор аннотаций во время компиляции. Я предполагаю, что вы могли бы использовать отражение (или... не отражение, так как это время компиляции?), Чтобы увидеть, содержит ли аннотированный класс поле, которое вы хотите.
Ответ 5
Здесь лучший способ, который я нашел, чтобы смоделировать это. Javadoc предотвращают, предотвращают немного, чтобы плохо расширяется..., но у подкласса id нет ИМЯ, это просто не сможет выполнить
public abstract class Foo {
protected final String NAME;
public Foo() {
String name="";
try {
name = (String) this.getClass().getDeclaredField("NAME").get(name);
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
NAME = name;
}
}
public class Bar extends Foo {
public static final String NAME = "myName";
}