如何在使用javaassist创建类时向方法添加@Override
注释?
ClassPool pool = ClassPool.getDefault();
CtClass ctClasz = pool.makeClass("test.ExampleImpl");
ctClasz.addInterface(pool.get(MyInterface.class.getName()));
CtMethod method = CtNewMethod.make ("@Override public void print() { System.out.println(\"Hello! \"); }", ctClasz);
ctClasz.addMethod(method);
System.out.println("Implementd: Interfaces:" + ctClasz.getInterfaces());
System.out.println("Methods: " + ctClasz.getMethods());
ctClasz.writeFile("D:");
此代码抛出异常如下:
Exception in thread "main" javassist.CannotCompileException: [source error] syntax error
near "@Override p"
at javassist.CtNewMethod.make(CtNewMethod.java:78)
at javassist.CtNewMethod.make(CtNewMethod.java:44)
at javaassist.Demo.main(Demo.java:17)
Caused by: compile error: syntax error near "@Override p"
at javassist.compiler.Parser.parseClassType(Parser.java:983)
at javassist.compiler.Parser.parseFormalType(Parser.java:191)
at javassist.compiler.Parser.parseMember1(Parser.java:51)
at javassist.compiler.Javac.compile(Javac.java:89)
at javassist.CtNewMethod.make(CtNewMethod.java:73)
... 2 more
答案 0 :(得分:7)
@Override
不是运行时注释,所以即使你可以添加它,它也不会有任何区别。
对于具有运行时效果(RetentionPolicy.RUNTIME
)的注释,您可以查看this question。
答案 1 :(得分:3)
添加注释并不感兴趣。因为它有@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)
,所以没有任何区别。所以,你不需要关心这个问题。
我会关注@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
保留的注释。
此anntotation具有@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)
保留意味着即使您在生成运行期间要生成的某些类时使用JAVASSIST添加它也不会更改任何内容。
注释对代码没有任何影响。当Java生成源时,这已被剥离。由于JAVASSIST生成代码,因此无需添加它。
根据documentation,保留可以配置为:
在JAVASSIST中添加 RUNTIME 或 CLASS 注释会很有趣(但对于CLASS来说,它不会那么有趣,请参阅here)。< / p>
答案 2 :(得分:2)
@Override仅对编译器有用。
它告诉编译器确保带注释的方法:
a. Overrides a method on the superclass
b. Implements an interface method.
当接口或超类发生变化时,这一点变得特别重要。您的类可能会编译,但您认为在接口或超类上定义功能的方法可能不再这样做。
所以@Override注释让编译器在这种情况下咆哮。
修改强>
示例:
public interface Foo {
void bar();
}
public class FooImpl {
public void bar() { ... }
}
public class MyFooExtension extends FooImpl {
public void bar() { .... }
}
现在,让我们说Foo和FooImpl改变:
public interface Foo {
void bar(String input);
}
public class FooImpl {
public void bar(String input) { ... }
}
你的MyFooExtension类仍然会编译,但该类中的“bar()”方法永远不会被调用。因此你的方法毫无用处。如果你添加@Override注释,你会得到一个编译错误,告诉你没有方法“void bar()”被覆盖,你必须修复你的类才能让它编译。</ p>