我将类,接口和枚举的源文件混合在一个包中,如下所示:
package com.mycompany.data;
class Dog {
// implementation
}
package com.mycompany.data;
class Cat {
// implementation
}
package com.mycompany.data;
enum Gender {
// gender options
}
package com.mycompany.data;
interface Animal {
// methods
}
// ... plus a lot more concrete classes and a few more interfaces ...
目标:让所有类实现新界面和新方法。
问题:我可以成功地将接口编织到类中,并排除枚举,但我无法弄清楚如何防止新接口被添加到接口中包装也是如此。
我的方面目前看起来像:
public aspect SecureAspect {
declare parents: com.mycompany.data.* && !java.lang.Enum+ implements Secure;
// add method from secure interface to everything implementing Secure
}
我的示例中匹配Dog
,Cat
和Animal
。
我之前尝试过:
declare parents: com.mycompany.data.* && java.lang.Object+ && !java.lang.Enum+ implements Secure;
因为Animal.class.getSuperclass() == null
而不是对象,但无济于事。
我知道我可以通过将接口从包中移出来解决这个问题(如果事实证明这是不可能的,我很乐意这样做),但我很好奇是否有办法排除类似的接口我做了Enums。
非常确定无所谓,但我正在使用javaagent进行加载时编织。
答案 0 :(得分:3)
这个问题已经过时了,但我发现它很有趣,并做了一些研究。
解决方案如下所示:
从ITD排除枚举和界面的方面:
package com.mycompany.aspect;
import com.mycompany.data.Secure;
public aspect SecureAspect {
declare parents :
!is(InterfaceType) && !is(EnumType) && com.mycompany.data.*
implements Secure;
public void Secure.doSomething() {
System.out.println("I am a secure " + this.getClass().getSimpleName());
}
}
顺便说一下,即使你不排除它们,enums仍然不会实现该接口。但是你会得到编译器错误"不能使用声明父类来生成枚举类型com.mycompany.data.Gender实现一个接口"。
验证ITD效果的驱动程序应用程序:
应用程序迭代所有相关的类,枚举,接口并检查它们是否确实实现了Secure
接口。由于Gender
子句,我们希望枚举Animal
和接口!is(InterfaceType) && !is(EnumType)
免于ITD。如果确实实现了接口,则会通过反射调用doSomething
方法,以便仔细检查ITD效果。
package com.mycompany.data;
public class Application {
public static void main(String[] args) throws Exception {
for (Class<?> clazz : new Class[] { Application.class, Cat.class, Dog.class, Gender.class, Animal.class }) {
String implementsYesNo = " does not implement";
for (Class<?> iface : clazz.getInterfaces()) {
if (iface == Secure.class) {
implementsYesNo = " implements";
Object instance = clazz.newInstance();
clazz.getMethod("doSomething").invoke(instance);
break;
}
}
System.out.println(clazz.getSimpleName() + implementsYesNo + " interface Secure\n");
}
}
}
控制台输出:
I am a secure Application
Application implements interface Secure
I am a secure Cat
Cat implements interface Secure
I am a secure Dog
Dog implements interface Secure
Gender does not implement interface Secure
Animal does not implement interface Secure
特别感谢 Andy Clement ,AspectJ维护者,他向我指出AspectJ 1.6.9 release notes(搜索&#34;类型类别类型模式&#34; )因为该功能在其他方面没有记录,即使它是AspectJ语言的官方部分。