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