gpt4 book ai didi

java - 使用注释修改方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:05:30 25 4
gpt4 key购买 nike

如何更改 Java 中方法的作用?

我的意思是,我正在尝试使用注释来制作以下代码

@Anno1(Argument = "Option1")
public class TestClass
{
@Anno2
public void test()
{
}

}

进入

public class TestClass
{
private static StaticReference z;

public void test()
{
z.invokeToAll();
}

}

这是我正在尝试做的一个非常简单的例子。 Anno1 会有很多可能的组合,但这不是我目前的问题。我的问题是如何将代码添加到方法 test()

如果可能,我正在寻找更通用的解决方案。例如。一种在方法中添加各种代码的方法(不仅仅是 .invokeToAll() 的方法)

到目前为止,我正在使用 import javax.annotation.processing.*; 并且我有以下代码,但我不知道如何从那里继续

private void processMethodAnnotations(RoundEnvironment env)
{
for (Element e : env.getElementsAnnotatedWith(Anno2.class))
{
//If it is a valid annotation over a method
if (e.getKind() == ElementKind.METHOD)
{
//What to do here :S
}else
{
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);
}
}
}

我找到了一些关于 Java 反射的信息,但我没有找到任何资源来帮助我完成我正在做的事情。

显然我在我的代码中扩展了 AbstractProcessor

我找到了这个教程 (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm) 但这涉及创建一个新类,而不仅仅是更改方法.并且 javax.lang.model.elements 不提供任何编辑该元素的方式(在我的例子中代表一种方法)。

我希望我的问题很清楚并且符合规则。如果不是请发表评论,我会澄清。谢谢。

最佳答案

注释处理对你来说是错误的方法,来自 Wikipedia :

When Java source code is compiled,annotations can be processed bycompiler plug-ins called annotationprocessors. Processors can produceinformational messages or createadditional Java source files orresources, which in turn may becompiled and processed, but annotationprocessors cannot modify the annotatedcode itself.

人们向您建议了正确的方法——AOP。具体来说,可以使用AspectJ。 “快速结果”方式是(如果您使用 Eclipse):

  1. 安装 AJDT (AspectJ 开发工具)

  2. 创建一个 AspectJ 项目并在其中添加您的类和注释

  3. 创建方面:

    公共(public)方面处理器{

     private StaticReference z;

    pointcut generic()
    // intercept execution of method named test, annotated with @Anno1
    // from any class type, annotated with @Anno2
    : execution(@Anno2 * (@Anno1 *).test())
    // method takes no arguments
    && args ();

    // here you have written what you want the method to actually do
    void around () : generic() {
    z.invokeToAll();
    }

现在您可以执行测试,您会看到它有效 ;) AJDT 会自动为您编译代码,因此不需要任何手动工作,希望这就是您所谓的“魔法”;)

更新:

如果您在 test() 方法中的代码依赖于 Anno1 注释值,那么在 aspect 内部您可以获得以这种方式执行的类注释:

void around () : generic()  {

Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();

String ArgumentValue = null;
for ( Annotation annotation : classAnnotations ) {
if ( annotation instanceof Anno1 ) {
ArgumentValue = ((Anno1) annotation).Argument();
break;
}
}

if ( ArgumentValue != null && ArgumentValue.equals("Option1")) {
z.invokeToAll();
}

}

哪里thisJoinPoint是一个特殊的引用变量。

更新 2:

如果你想在你的方面添加System.out.println(this),你需要在那里写System.out.println(thisJoinPoint.getThis()),刚刚测试过,它可以工作。 thisJoinPoint.getThis() 返回“this”但不完全是;事实上,这是对象变量,如果你想获得任何属性,你需要强制转换或使用反射。并且 thisJoinPoint.getThis() 不提供对私有(private)属性的访问。

好吧,现在看来您的问题已经得到解答,但是如果我遗漏了什么,或者您通过这种方式遇到了其他问题/问题 - 请随时提问 ;)

关于java - 使用注释修改方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4851429/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com