为了账号安全,请及时绑定邮箱和手机立即绑定

Java 中的抽象常量

Java 中的抽象常量

Helenr 2022-08-17 17:04:51
我想创建一个未在超类中实现的常量,以强制子类实现它。我发现(关于此主题)的最佳解决方案是创建一个将返回常量值的抽象方法。我假设不可能做这样的事情:abstract final static String Name;但我仍然有希望,因为Java在Serializable接口中使用了这样的东西。有人知道他们是怎么做到的吗?有可能在我自己的课堂上复制它吗?
查看完整描述

5 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

这样的常量不能,因为字段在类的所有实例(包括所有子类的实例)之间共享。下面介绍如何将其实现为非静态常量:staticstatic


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

  }

}

顺便说一句,不是接口的一部分。serialVersionUIDSerializable


查看完整回答
反对 回复 2022-08-17
?
LEATH

TA贡献1936条经验 获得超6个赞

serialVersionUID接口不会强制执行字段存在,因为接口无法强制执行字段的存在。你可以声明一个实现的类,它将编译得很好,没有字段在那里。SerializableSerializableserialVersionUID


检查字段在工具中是硬编码的。一个例子是JDK java.io.ObjectStreamClass.getSerialVersionUID()方法,它通过反射加载值:serialVersionUIDserialVersionUID


/**

 * 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;

}


查看完整回答
反对 回复 2022-08-17
?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

我不推荐它,但如果你非常需要它,你可以在Checkstyle中创建一个正则表达式检查,并强迫人们实现静态变量。


查看完整回答
反对 回复 2022-08-17
?
FFIVE

TA贡献1797条经验 获得超6个赞

当一个类实现没有您在 IDE 中看到的小消息时,编译时会发出警告。如果你想创建这样的东西,你可以,但这个过程似乎很复杂。解决方案就在这个答案中。SerializableserialVersionUIDjavac

它们详细介绍了,但一般思想是创建注释和注释处理器,并在编译期间使用注释处理器。我猜你可以使用反射(或者...不是反射,因为它是编译时间?以查看带注释的类是否包含所需的字段。


查看完整回答
反对 回复 2022-08-17
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

这是我发现的模拟它的最佳方法。Javadoc 防止防止有点不好扩展...但是id子类没有NAME,它将无法执行


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";

}


查看完整回答
反对 回复 2022-08-17
  • 5 回答
  • 0 关注
  • 151 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信