我们正在构建一个工具(供内部使用),只有在从源代码中删除javax.persistence.GeneratedValue注释时才会起作用(我们在工具中设置了Id,由于GeneratedValue注释而被拒绝)。 ..但是对于正常操作,我们需要这个注释。
如何在运行时删除Java Annotation(可能使用Reflection)?
这是我的班级:
@Entity
public class PersistentClass{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
// ... Other data
}
这是我希望能够在运行时将其更改为:
@Entity
public class PersistentClass{
@Id
private long id;
// ... Other data
}
可以在类本身上执行此操作:
// for some reason this for-loop is required or an Exception is thrown
for (Annotation annotation : PersistentClass.class.getAnnotations()) {
System.out.println("Annotation: " + annotation);
}
Field field = Class.class.getDeclaredField("annotations");
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = (Map<Class<? extends Annotation>, Annotation>) field.get(PersistentClass.class);
System.out.println("Annotations size: " + annotations.size());
annotations.remove(Entity.class);
System.out.println("Annotations size: " + annotations.size());
如果您可以从字段中获取注释图,则应用相同的解决方案。
答案 0 :(得分:2)
您无法在运行时删除注释。反思只检查代码。
你能做的是:
您可以删除使用字符串黑客工具(如Perl或SED)的注释。这些可能非常可靠,但用于执行此操作的实际命令可能非常神秘。
如果您能够以原则方式修改源代码版本,可以使用program transformation system (PTS)这些是将源解析为编译器数据结构的工具,让您指定(结构化)要应用的“转换”代码,以可靠的方式将变换应用于结构,然后为已更改的程序重新生成(有效)源代码。
一个好的PTS可以让你根据表面语法指定这样的变换:
<progress max="45" value="30"></progress>
其中模式本质上是目标语言代码的片段(例如,Java)。
(我碰巧构建了其中一个PTS)。特定规则(对于我的PTS)可能如下所示:
if you see *this* pattern, replace it by *that* pattern
这说,“如果您找到包含带有任何值的'策略'属性的GeneratedValue注释的注释的列表,请替换它( - &gt; )没有注释的列表注释“。[这是因为注释列表是可交换的,所以我们总是可以表现为有趣的成员是列表的最后一个成员。](”标记是 metaquotes ;它们将规则语言的语法与模式中的Java语法区分开来。)
答案 1 :(得分:0)
创建一个新的库,复制并过滤实体源以删除注释。这既不硬也不干净。
您也可以尝试使用ClassLoader和字节码操作。但是类加载是一个粪坑。