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

查看:188
本文介绍了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()中是否有一种方法(优雅的Groovy方法?)来标识子类调用的类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魔术来解决问题,利用了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天全站免登陆