是否有可能使用注释修补scala final类?

时间:2015-09-18 21:08:43

标签: java scala annotations objectify

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

1 个答案:

答案 0 :(得分:0)

最简单的解决方案是定义您自己的等级为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();
    }
}