Groovy / Java中有什么方法可以识别调用静态方法的子类?

时间:2019-07-13 14:17:11

标签: java groovy subclass static-methods abstract

Groovy如此强大,我想知道是否有简单的方法可以做到这一点。

场景:

我有一个抽象类AbstractSequence。然后,我有两个(实际上是更多)子类,分别称为say CasedSequenceLowerCaseSequence。这些具体类中的每一个都必须具有一个“身份映射表”,即像Set一样,但是可以根据功能相等性(覆盖equalshashCode来提取元素

所以我们有:

class CasedSequence extends AbstractSequence {
    static Map identityMap = [:]
...

class LowerCaseSequence extends AbstractSequence {
    static Map identityMap = [:]

实际上,由于需要花费太长时间解释的原因,在各个类中对这些标识映射的操纵还使用了许多静态方法,从一个子类到另一个子类都相似/相同。因此,我想知道如何重构身份映射到抽象基类中(然后在其中迁移很多重复的静态方法)。

这导致我想到这个:

abstract class AbstractSequence {

    static Map getIdentityMap( Class clazz ) {
        if( ! ( clazz in identityMaps )) 
            identityMaps[ clazz ] = [ : ]
        identityMaps[ clazz ]
    }
    static Map identityMaps = [:]

然后在具体的类中,每次您想要使用身份映射时,都必须这样做:

class CasedSequence extends AbstractSequence {
    def someMethod( CasedSequence seq1 ){
        CasedSequence seq2 = getIdentityMap( CasedSequence )[ seq1 ] 
...

同样,要解释为什么需要这种方式检索东西太复杂了……但是我只是想知道AbstractSequence.getIdentityMap()中是否有一种方法(一种优雅的Groovy方法?)来标识该类。子类调用getIdentityMap(),而不必将此类作为参数传递?

PS我宁愿不使用Thread.stackTrace:它很麻烦,并且不会提供实际的类对象,只有类名以及Groovy中的堆栈跟踪很常见。我在考虑Groovy反射,Groovy元类...

1 个答案:

答案 0 :(得分:0)

将有兴趣听取任何Groovy专家的意见。

同时,我利用了一些Groovy魔术作为变通办法,利用了Groovy GDK向class类添加了一些方法的事实,其中一个是newInstance()-非常有用。根据所寻找的序列是否已经在身份图中,“生成或获取”序列对象。

    static makeOrGet( String string, Class clazz ) {
        def dummySeq = clazz.newInstance( DUMMY_STRING )
        // NB the constructor identifies the string DUMMY_STRING to prevent this new object being 
        // properly "registered" (i.e. put in the identity map), which would be wrong because 
        // the dummy seq is just to find out whether the sequence with "string" is actually 
        // present in the map

        def seq
        // disguise the dummy sequence to flush out an existing sequence with String "string"
        dummySeq.string = string
        if( dummySeq in getIdentityMap( clazz ) )
            seq = getIdentityMap( clazz )[ dummySeq ]
        else
            // NB constructor puts the new "clazz" object in the identity map
            seq = clazz.newInstance( string )
        seq
    }

...因此可以用各种不同的类作为参数2调用上述方法,然后传递clazz类的对象,该对象可以从身份映射中提取或构造(并放入映射中)。 / p>