我想处理Circle.getArea()
使用Aspectj从方法抛出的异常。
Shape.java
package Shapes;
public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter(){
return 2 * Math.PI * this.radius;
}
public double getArea(){
return Math.PI * this.radius * this.radius;
}
}
Rectangle.java
package Shapes;
public class Rectangle {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getPerimeter() {
return 2 * (this.width + this.height);
}
public double getArea() {
return this.width * this.height;
}
}
Circle.java
package Shapes;
public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter() {
return 2 * Math.PI * this.radius;
}
public double getArea() {
throw new RuntimeException("Oops, I don't know how to calculate this :(");
}
}
Main.java
package Shapes;
public class Main {
public static void main(String[] args) {
try {
Shape s;
s = (Shape) new Rectangle(2, 10);
System.out.println("The area of " + s + " is " + s.getArea());
s = (Shape) new Rectangle(-2, 10);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());
s = (Shape) new Circle(-2);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());
s = (Shape) new Circle(2);
System.out.println("The area of " + s + " is " + s.getArea());
}
catch(Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
解决
package Shapes;
privileged public aspect Resolve {
declare parents: Rectangle implements Shape;
declare parents: Circle implements Shape;
public String Rectangle.getName(){
return "Rectangle";
}
public String Circle.getName(){
return "Circle";
}
public String Rectangle.toString(){
return this.getName()+"("+this.width+","+this.height+")";
}
public String Circle.toString(){
return this.getName()+"("+this.radius+")";
}
after() throwing(RuntimeException e) : execution(* Circle.*()){
handleException();
}
protected void handleException()
{
System.out.println("Error detected");
}
}
当前输出为:
The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
Error: Oops, I don't know how to calculate this :(
我想避免打印“错误:糟糕,我不知道如何计算此:(”,并且我需要最后获取圆对象的实际面积。但是,我无法更改任何.java文件。全部更改应使用Resolve.aj文件。
你需要使用around
建议的,而不是后:
Object around () : execution(* Circle.*()){
try {
return proceed();
}
catch(Exception e)
{
handleException();
}
return null;
}
代码输出:
The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
The area of Circle(2.0) is 0.0
为什么我们使用周围的建议而不是后面的建议?
非常非正式的around
咨询截取一个给定的连接点,并能注入新的行为前,后,和而不是该连接点。本proceed
是一个特殊的功能,允许around
建议继续的执行joinpoint
。
从的类型的建议通过的AspectJ支持(即 before
,after
和around
),该around
建议是唯一一个允许返回的值和/或使用proceed
。这样一来,around
建议就可以多次执行相同的联接点,或者根本不执行该联接点。此外,你甚至可以在不同的上下文中执行拦截的连接点(例如,更改方法参数的值)。
可以在此SO Thread上找到有关建议和进行工作的更多信息。
我们的around
建议将拦截类中方法的所有执行连接点Circle
,并相应地处理这些方法引发的异常。