【问题标题】:java/groovy/grails instanceof failsjava/groovy/grails instanceof 失败
【发布时间】:2016-03-09 16:05:34
【问题描述】:

我有一个名为 Video 的类和这个类的一个对象(这里称为“b”)

这是测试用例:

log.debug b
log.debug b.class
log.debug (b.class == Video)
log.debug (b instanceof Video)
log.debug (b.instanceOf(Video))
log.debug (b in Video)

输出是:

DEBUG NavLinkHelperTagLib  - product.content.Video : 4352
DEBUG NavLinkHelperTagLib  - class product.content.Video
DEBUG NavLinkHelperTagLib  - true
DEBUG NavLinkHelperTagLib  - false
DEBUG NavLinkHelperTagLib  - true
DEBUG NavLinkHelperTagLib  - false

谁能告诉我为什么 instanceof 失败了?!

编辑:

我感觉这与 GORM 有关。这是我的捐赠课程:

abstract class Product implements Serializable {

    static hasMany = [additionalContents:AdditionalContent]
}

abstract class AdditionalContent implements Serializable{
    static belongsTo = [product:Product]

}

class Video extends AdditionalContent {
}

我认为这里的问题是延迟加载?但是当这是代理/延迟问题时,通常我会在调用 .getClass() 时看到类似 Video$$javaassist 的内容,但我没有看到这个...

【问题讨论】:

  • instanceOf方法是如何实现的?
  • 这个方法来自groovy/grails

标签: java hibernate grails groovy


【解决方案1】:

这与 Hibernate / Gorm 相关。您的域对象很可能由 Hibernate 代理。因此,您不能使用 Java instanceOf

Grails 团队意识到了这个问题,因此他们在每个 Grails 域对象上引入了instanceOf() 方法。以下引用来自Grails reference

您可以通过使用 GORM 的 instanceOf 方法:

def person = Person.get(1)

断言 Pet.list()[0].instanceOf(Dog)

因此只能使用instanceOf() 方法比较域类。

要查看instanceOf 是如何实现的,您需要使用JD-GUI 反编译您的Video 域类。

在 Grails 3 应用程序中,这是由 trait GormEntity 实现的。

@Traits.TraitBridge(traitClass=GormEntity.class, desc="(Ljava/lang/Class;)Z")
  public boolean instanceOf(Class arg1)
  {
    // Byte code:
    //   0: invokestatic 88 ch/silviowangler/zscsupporter/Game:$getCallSiteArray    ()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
    //   3: astore_2
    //   4: aload_2
    //   5: ldc_w 548
    //   8: aaload
    //   9: ldc -104
    //   11: aload_0
    //   12: aload_1
    //   13: invokeinterface 209 4 0
    //   18: invokestatic 182   org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation:booleanUnbox (Ljava/lang/Object;)Z
    //   21: ireturn
    //   22: nop
    //   23: nop
    //   24: nop
    //   25: nop
    //   26: nop
    //   27: nop
    //   28: nop
    //   29: nop
    //   30: athrow
    // Local variable table:
    //   start  length  slot    name    signature
    //   0  22  0   this    Game
    //   0  22  1   arg1    Class
  }

这是了解instanceOf 方法行为方式的唯一方法。

【讨论】:

  • 嗯,是的。我知道这一点。但是我在我的项目中到处都使用了 instanceof(而且非常大)并且从来没有遇到过问题。首先,我不想用 .instanceOf() 替换所有 instanceof 关键字。其次,我需要到处做一个空值。我想了解 WHEN instanceof 失败,或者换句话说,它在什么情况下失败。
  • 还有。 Normall,当 Hibernate 使用代理并且您调用 object.getCLass() 时,您会得到如下内容: Video_$$javaassist* 我没有得到。见这里:stackoverflow.com/a/2975123/921636
【解决方案2】:

不知道为什么instanceof(我第一次写instanceOf但意思是java关键字)失败,但检查类型的正常方法是in

log.debug b in Video

应该返回true

【讨论】:

  • 请注意方法 instanceOf 有效,但 java 关键字 instanceof 无效
  • 这就是我的意思。我会纠正错字。但我还是不明白为什么它不起作用......
  • 我现在试试“in”。但这不是“纯”java 为什么对?当谈到 instanceof 时,我很想留在纯 Java 方面。否则我可以只使用我发布的其他两个返回 true 的选项
  • "in" 返回和 instanceof 一样 --> false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
相关资源
最近更新 更多