まず、独自のソリューションが動作しないことができます:withincode()
がポイントカットのパラメータを取りませんので!withincode(call(int MyClass.foo(int)))
はコンパイルされません。 、署名のみ。だからそれは本当にあるべきです:!withincode(int MyClass.foo(int))
。
第2に、自分の答えのソリューションは間接的な再帰ではなく、直接的な再帰のためだけに働くので、あなたが本当に望むのはあなたの初期のソリューションと似ています。あなたが見ることができるように、
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
Application application = new Application();
System.out.println("Directly recursive factorials:");
for (int i = 0; i < 12; i++)
System.out.printf("%2d! = %10d%n", i, application.factorial(i));
System.out.println("\nIndirectly recursive factorials:");
for (int i = 0; i < 12; i++)
System.out.printf("%2d! = %10d%n", i, application.factorial_indirect(i));
}
public int factorial(int i) {
return i > 1 ? i * factorial(i - 1) : 1;
}
public int factorial_indirect(int i) {
return helper(i);
}
public int helper(int i) {
return i > 1 ? i * factorial_indirect(i - 1) : 1;
}
}
それが今度は、元を呼び出すhelper(int)
を呼び出すためfactorial_indirect(int)
が間接再帰を経由してそうに対しfactorial(int)
は、直接再帰による階乗を計算します。
ドライバアプリケーション:ここでは一例ですメソッドを再度実行します。私は両方の状況に対応し、最初の呼び出しをブロックし、直接的または間接的に再帰的な呼び出しをブロックしないという側面を提示します。
アスペクト比:あなたの質問から元のポイントカットはほぼ正しかった
、それだけでcflowbelow()
の代わりcflow()
を使用している必要があります。
私は実際に例外を投げているわけではなく、プログラムの流れを中断しないようにデモ目的でログするだけです。
package de.scrum_master.aspect;
import de.scrum_master.app.Application;
public aspect CheckBounds {
pointcut factorialCall() :
call(int Application.factorial*(int));
pointcut initialFactorialCall(int i) :
factorialCall() &&
!cflowbelow(factorialCall()) &&
args(i);
pointcut initialFactorialCall2(int i) :
factorialCall() &&
!withincode(int Application.factorial*(int)) &&
args(i);
before(int i) : initialFactorialCall(i) {
if (i < 1 || i == 10) {
System.out.println(new IllegalArgumentException("x must be >=1 and != 10"));
}
}
}
コンソールログ:
Directly recursive factorials:
java.lang.IllegalArgumentException: x must be >=1 and != 10
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
java.lang.IllegalArgumentException: x must be >=1 and != 10
10! = 3628800
11! = 39916800
Indirectly recursive factorials:
java.lang.IllegalArgumentException: x must be >=1 and != 10
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
java.lang.IllegalArgumentException: x must be >=1 and != 10
10! = 3628800
11! = 39916800
あなたが直接および間接的な再帰例ともに0と10の初期値のための私のテスト条件ログのエラーを見ることができるように。今、私たちはbefore()
アドバイスにinitialFactorialCall2(i)
に切り替えた場合、間接的なケースのためにログに変わり:
Indirectly recursive factorials:
java.lang.IllegalArgumentException: x must be >=1 and != 10
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
java.lang.IllegalArgumentException: x must be >=1 and != 10
10! = 3628800
java.lang.IllegalArgumentException: x must be >=1 and != 10
11! = 39916800
例外もfactorial_indirect(10)
の内部呼び出しのために記録されます11!
の間違った反応を注意してください。これは明らかに間違っているので、代わりにcflowbelow()
ソリューションを利用したいと考えています。
説明をありがとう!しかし、奇妙なことに、私はオリジナルの解法で構文エラーを起こさず、直接再帰のために働いていました。何か案は? –
不可能です。コピー&ペーストを使用してIDEで修正したものをここで調整するのを忘れた可能性があります。私は私の答えに記載されている結果で両方のアプローチを試みました。ここからもう一度コピーして、自分で見てください。 :-) – kriegaex
こんにちは、私は疑問に思っていました。あなたはどのようにしますか?入力を常に1にしたい場合は、最初の呼び出しでのみ、パラメータの値を1に変更しますか? –