【问题标题】:Is it possible to monkey patch a scala final class with an annotation?是否可以用注释修补 scala final 类?
【发布时间】:2015-09-18 21:08:42
【问题描述】:

我使用 Scala 作为我的语言。我使用 Google Objectify 作为我的持久性 API 来将对象存储到 Google App Engine 的数据存储中。任何要通过 Objectify 存储在 Google App Engine Datastore 中的类都必须有一个 @Entity 注释作为该类的前缀。您通常将此注释应用于您自己的类,以便在您自己的应用程序或域中使用。在我的一个类中,我希望能够定义一个 Option[String] 类型的类属性。为此,我需要能够将 @Entity 或 @Subclass 注释(Objectify 注释)应用于 Option 类。但这是一种内置的 Scala 语言类型。有没有办法使用隐式类或类型或 Scala 宏对语言进行“猴子修补”,以便我在事后将该注释添加到内置的 Scala 语言类型?

【问题讨论】:

    标签: java scala annotations objectify


    【解决方案1】:

    最简单的解决方案是定义您自己的等价于Option 的类以及与Option 之间的隐式转换。

    否则,Scala 本身无法这样做,但您可以使用 ASM 或 Javassist 等字节码操作库之一。有一个为 ASM here(但似乎不完整)和 Javassist here 动态添加注释的示例。 Javassist 似乎更容易使用(没有翻译成 Scala,但很简单):

    import java.lang.reflect.Field;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtField;
    import javassist.bytecode.AnnotationsAttribute;
    import javassist.bytecode.ClassFile;
    import javassist.bytecode.ConstPool;
    import javassist.bytecode.annotation.Annotation;
    
    public class AddingAnnotationDynamically {
        public static void main(String[] args) throws Exception {
            ClassPool cp = ClassPool.getDefault();
            CtClass cc = cp.get("scala.Option");
            // Without the call to "makePackage()", package information is lost
            cp.makePackage(cp.getClassLoader(), pkgName);
            ClassFile cfile = cc.getClassFile();
            ConstPool cpool = cfile.getConstPool();
    
            AnnotationsAttribute attr =
                    new AnnotationsAttribute(cpool, AnnotationsAttribute.visibleTag);
            Annotation annot = new Annotation(annotationName, cpool);
            attr.addAnnotation(annot);
            cfile.addAttribute(attr);
            // Changes are not persisted without a call to "toClass()"
            Class<?> c = cc.toClass();
        }
    }
    

    【讨论】:

    • 谢谢。我会尝试你的第一个建议。
    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 2012-10-26
    • 2016-10-12
    • 2010-09-19
    • 1970-01-01
    • 2019-09-12
    • 2016-08-10
    相关资源
    最近更新 更多