Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AspectJ-继承的';父母';班_Java_Inheritance_Aspectj - Fatal编程技术网

Java AspectJ-继承的';父母';班

Java AspectJ-继承的';父母';班,java,inheritance,aspectj,Java,Inheritance,Aspectj,目标:从我的任何@Entity类调用类的静态过滤器()。返回列表似乎是不可能的 需要在用户类中隐藏静态ORMEntity filter()方法。 但静态方法是在编译时解决的 我看到的唯一解决方案是在.java文件中生成static filter()方法,就像lombok可以使用getter/setter一样。正如我们在您自己的答案下的讨论中所解释的那样,我怀疑您的应用程序设计是否真的有意义,但是为了它的价值,我为您准备了一个解决方案。这个解决方案是我在中描述的更复杂案例的简化版本 这是我的Ecl

目标:从我的任何
@Entity
类调用类的
静态过滤器()。返回
列表似乎是不可能的

需要在用户类中隐藏静态ORMEntity filter()方法。 但静态方法是在编译时解决的


我看到的唯一解决方案是在.java文件中生成static filter()方法,就像lombok可以使用getter/setter一样。

正如我们在您自己的答案下的讨论中所解释的那样,我怀疑您的应用程序设计是否真的有意义,但是为了它的价值,我为您准备了一个解决方案。这个解决方案是我在中描述的更复杂案例的简化版本

这是我的Eclipse布局,其中包含两个源文件夹和一个执行两阶段编译过程的Windows批处理文件

  • 首先编译一个APT处理器,负责为每个注释类创建一个方面
  • 然后在下一个AspectJ编译步骤中将这个处理器应用到Java源代码中
以下是我的目录布局的屏幕截图:

正如您所看到的,类
应用程序
不能由Eclipse直接编译,您确实需要使用批处理文件

标记注释:

注意,该类必须存储在src_apt中,以便对用户可见 注释处理器
EntityProcessor
稍后

package de.scrum\u master.app;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface实体{}
两个带注释的示例实体:

package de.scrum\u master.app;
@实体
公共类用户{}
package de.scrum\u master.app;
@实体
公共类组{}
驱动程序应用程序:

此应用程序依赖APT在实际看到所使用的静态方法之前完成其工作

package de.scrum\u master.app;
公共类应用程序{
公共静态void main(字符串[]args){
User.filter();
Group.filter();
}
}
方面打印方法签名:

这是原始方面的简化版本,只打印方法签名,不声明任何父方法或静态方法。这只是为了以后获得更好的日志输出:

package de.scrum\u master.aspect;
公共方面{
切入点静态过滤器():
调用(公共静态*filter());
before():staticFilter(){
System.out.println(此连接点);
}
}
注释处理器:

此注释处理器搜索用
@Entity
注释的类,并创建一个方面,为每个类引入静态方法
filter()

package de.scrum\u master.app;
导入java.io.*;
导入java.util.*;
导入javax.tools.*;
导入javax.annotation.processing.*;
导入javax.lang.model.*;
导入javax.lang.model.element.*;
@SupportedAnnotationTypes(值={“*”})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
公共类EntityProcessor扩展了AbstractProcessor{
私人文件管理器;
@凌驾
公共void init(ProcessingEnvironment环境){
filer=env.getFiler();
}
@凌驾

public boolean process(set)声明类型为
ORMEntity
,因为在那里声明了
filter()
method。即使您使用非静态方法,该方法本身仍然会在
ORMEntity
中“声明”,但您甚至没有使用实例方法,因此在静态方法的情况下,您不应该从继承的角度来考虑。我不确定您在这里试图实现什么,因此如果您详细说明一下,它可能会很有用是的,我知道那是一个拥有过滤器的实体方法。我曾认为使用aspectj,我可以从任何地方继承此方法。这是可行的,但即使我使用User类调用它,调用方仍保留ORMEntity。事实上,我想从我的任何@Entity类静态调用此筛选器方法。只是为了得到“漂亮的”“简单的”代码。而不是调用ORMEntity.filter(User.class);我会在后台调用User.filter();谁在调用ORMEntity.filter(User.class);这就是为什么我要搜索正确的类调用方。好吧,关于静态方法调用的一些细节:编译器允许你说
Subclass.staticMethod()
,即使
staticMethod()
本身是在一个超类中声明的,这只是编译器对您的意图宽容的一种情况。它实际上是在后台将您的方法调用转换为
DeclaringClass.staticMethod()
。另一方面,如果我理解正确,您希望知道其代码实际调用静态方法的类。这完全可以通过
调用(…)
键入切入点,事实上表达式是:
thisEnclosingJoinPointStaticPart
是,然后我得到包含User.filter()的类;语句。Main.class(假设Main方法在Main类中)。而不是User.classWell,那么答案就在我前面评论的第一部分,这是不可能的。Static方法是一个静态方法,它是静态连接的(因此得名)在编译时,根据调用它的类型。如果在
子类
上调用它,但
子类
本身没有定义具有该名称和兼容参数的静态方法,则编译器会将其静默地“重写”为
DeclaringClass.staticMethod()
。问题不在于它不可能,而在于它毫无意义!你想改变JVM的工作方式。这不是AspectJ的问题!!!如果你真的坚持你可以使用ITD为每个
@实体
类冗余声明方法。然后你得到了你想要的,但我觉得它效率低下