Groovy/Java 中有什么方法可以识别调用静态方法的子类? [英] Any way in Groovy/Java to identify the subclass calling a static method?

查看:24
本文介绍了Groovy/Java 中有什么方法可以识别调用静态方法的子类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Groovy is so powerful I wonder whether there's an easy way to do this.

场景:

我有一个抽象类,AbstractSequence.然后我有两个(实际上更多)子类,称为 CasedSequenceLowerCaseSequence.这些具体的类中的每一个都必须有一个身份映射",即像一个 Set,但可以根据功能相等(覆盖 equalshashCode).

I have an abstract class, AbstractSequence. Then I have two (more in reality) subclasses, called say CasedSequence and LowerCaseSequence. Each of these concrete classes has to have an "identity map", i.e. like a Set but where it is possible to extract an element based on functional equality (overriding of equals and hashCode).

所以我们有:

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

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

事实上,由于需要花很长时间解释的原因,在各个类中操作这些身份映射也使用了许多静态方法,从一个子类到另一个子类都是相似/相同的.所以我想知道如何重构以将身份映射放在抽象基类中(然后将大量重复的静态方法迁移到那里).

In fact, for reasons that would take too long to explain, manipulation of these identity maps in the respective classes also uses lots of static methods, all similar/identical from one subclass to the other. So I wondered how one might refactor to put the identity maps in the abstract base class (and then migrate a lot of the repetitive static methods there).

这让我想到了这个:

abstract class AbstractSequence {

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

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

and then in the concrete classes, each time you want to use the identity map you have to do this:

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

同样,解释为什么需要以这种方式检索东西太复杂了……但我只是想知道在 AbstractSequence.getIdentityMap() 识别调用 getIdentityMap() 的子类的类,而不是必须将这个类作为参数传递?

Again, it's too complicated to explain why you need to retrieve things this way... but I'm just wondering whether there's a way (an elegant Groovy way?) in AbstractSequence.getIdentityMap() to identify the class of the subclass calling getIdentityMap(), rather than having to pass this class as a parameter?

PS 我宁愿不使用 Thread.stackTrace:它很麻烦,并且不会提供实际的类对象,只有类名,而且 Groovy 中的堆栈跟踪是狂野的.我更多地考虑 Groovy 反射、Groovy 元类......

PS I'd rather not use Thread.stackTrace: it's cumbersome and won't deliver the actual class object, only the class name, and also stack traces in Groovy are wild. I'm thinking more in terms of Groovy reflection, Groovy metaclasses...

推荐答案

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

Would be interested in hearing from any Groovy gurus about this.

与此同时,我利用了 Groovy GDK 向 class 类添加了一些方法,其中一个是 newInstance() - 非常有用.这取决于所寻找的序列是否已经在身份映射中生成或获取"一个序列对象.

In the mean time I have used a bit of Groovy magic for a workaround, taking advantage of the fact that the Groovy GDK adds some methods to the class class, one being newInstance() - pretty useful. This "makes or gets" a sequence object depending on whether or not the sought sequence is already in the identity map.

    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 类的对象,从身份映射中提取或构造(并放入映射中)).

... so the above method can be called with various different classes as parameter 2 and then delivers an object of class clazz, either extracted from the identity map or constructed (and put in the map).

这篇关于Groovy/Java 中有什么方法可以识别调用静态方法的子类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆