【问题标题】:Java - An interface that has static field pointing to class name of its sub class?Java - 具有指向其子类的类名的静态字段的接口?
【发布时间】:2012-03-23 13:37:32
【问题描述】:

我想要一个接口,它的子类可以继承一个静态字段,该字段指向子类的名字。

我该怎么做?

例如在我的脑海中(代码无法使用):

public interface ILogger<A> {

    public static String LogTag = A.class.getName();
}

public class Sub implements ILogger<Sub> {

    public Sub() {
        Log.debug(LogTag, ...);
    }
}

【问题讨论】:

    标签: java generics reflection interface


    【解决方案1】:

    在 Java 中,与 C++ 不同,由于泛型的实现方式,这是不可能的。在 Java 中,每个泛型类型只有一个类,而不是每次使用不同类型参数时都有多个副本(这称为 erasure)。因此,不能有一个变量指向其子类型的类对象,因为可以有许多子类型,但静态字段总是只有一个副本。这与 C++ 形成鲜明对比,在 C++ 中,每次实例化 ILogger 模板时,您都会获得该静态字段的自己的副本。

    一种可能的近似方法是将Map 作为将类对象与字符串相关联的静态字段,如

    public static final Map<Class, String> classMap = new HashMap<Class, String>();
    

    然后您必须让每个子类型显式地将其自身添加到此映射中,可能使用静态初始化器:

    public class Sub implements ILogger<Sub> {
    
        static {
            ILogger.classMap.put(Sub.class, /* ... value ... */);
        }
    
        public Sub() {
            Log.debug(LogTag, ...);
        }
    }
    

    希望这会有所帮助!

    【讨论】:

    • 谢谢erasure的概念,我现在才知道。但我希望有一个更简洁的解决方案。我可以输入public static final String LogTag = Sub.class.getName(),而不是您的代码。但是,再次感谢:-)
    • 很遗憾,Java 中没有更简洁的解决方案。
    • Downvoter-您能解释一下这个答案有什么问题或如何改进它吗?
    • @templatetypedef 不用担心,您的回答对我很有帮助。如果您有使用 Android 的经验,请您帮我解决这个问题:stackoverflow.com/questions/2561161/…
    • @StephenC:是的。但从另一个角度来看。我可以编写自己的记录器,它将Sub.class 作为日志标签,而不是字符串。
    猜你喜欢
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 2011-07-09
    • 2021-10-08
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多