AspectJ 環境を構築しよう

Last Updated : 2003/4/29
asato <asato@ncfreak.com>

[ TOP ]

注意

用語の使い方について曖昧な部分があります:

Introduction (Inter-type declarations)

フィールドの Introduction

考えられるフィールドの Introduction の種類には、以下のようなものがあります: しかし、AspectJ ではこれら可視性の意味が通常の Java でのものと異なり、また、一部サポートされてないものもあります:

参考ドキュメント

フィールドの Introduction - その 1

(1.1rc1 OK)

アスペクト内で Introduction された private なフィールドには、そのクラスからはアクセスできません。もしクラスからのアクセスが必要なら public にするか package-protected (default) にする必要があります (package-protected の場合には、クラスとアスペクトを同一のパッケージ内に置く必要があります)。

public class Main {

	public static void main(String[] args) {
		new Main().method();
	}

	public void method() {
		System.out.println(str); // private で Introduction された
		                         // フィールドなのでアクセスできない。
		                         // したがって、コンパイルエラー
	}
}
public aspect MainAspect {
	private String Main.str;
}
もし prtivate ととして str フィールドを宣言するのではなく、デフォルトで宣言するか (Main クラスと MainAspect アスペクトが同じパッケージ内で宣言されていると仮定して)、あるいは public として宣言すると、上記のコードはコンパイルできます:
public aspect MainAspect {
	public String Main.str;
}

フィールドの Introduction - その 2

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {

		Main main = new Main();

		main.method();
		main.method();
	}

	public void method() {
		System.out.println("method");
	}
}
public aspect MainAspect {

	private int Main.count;

	before(Main main) : target(main) && call( void Main.method() ) {

		System.out.print(main.count + ": ");
		main.count++;
	}
}
java> java -cp dest aoptest.Main
0: method
1: method

フィールドの Introduction - その 3

(1.1rc1 OK)

public class Main {

	private String str = "aaa";

	public static void main(String[] args) {
		new Main().method();
	}

	public void method() {
		System.out.println(str);
	}
}
public aspect MainAspect {

	private String Main.str; // 同じフィールド名でもコンパイルできるのか?
	                            // YES
}
例 2:
public class Main { // 変更なし

	private String str = "aaa";

	public static void main(String[] args) {
		new Main().method();
	}

	public void method() {
		System.out.println(str);
	}
}
public aspect MainAspect {

	private String Main.str = "xxx";

	before(Main main) : target(main) && call( void Main.method() ) {
		System.out.print(main.str + ": ");
	}
}
java> java -cp dest aoptest.Main
xxx: aaa

フィールドの Introduction - その 4 : 抽象クラスに対して

(1.1rc1 OK)

public abstract class AbstractMain { }
public class Main extends AbstractMain {

	public static void main(String[] args) {

		System.out.println( new Main().str );
	}
}
public aspect MainAspect {

	public String AbstractMain.str = "aaa"; // public にしているのは簡単のため
}
java> java -cp dest aoptest.Main
aaa

フィールドの Introduction - その 5 : 抽象クラスに対して - その 2

(1.1rc1 OK)

public abstract class AbstractMain { }
public class Main extends AbstractMain {

	public static void main(String[] args) {

		MainAspect.printString( new Main() );
	}
}
public aspect MainAspect {

	private String AbstractMain.str = "aaa";

	public static void printString(AbstractMain main) {
		System.out.println( main.str );
	}
}
java> java -cp dest aoptest.Main
aaa

フィールドの Introduction - その 6 : interface に対して

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {

		System.out.println( new Main().str );
	}
}
public aspect MainAspect {

	public String MainInterface.str = "aaa";
}
java> java -cp dest aoptest.Main
aaa

フィールドの Introduction - その 7 : interface に対して - その 2

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {

		MainAspect.printString( new Main() );

	}
}
public aspect MainAspect {

	private String MainInterface.str = "aaa";


	public static void printString(MainInterface main) {
		System.out.println( main.str );
	}

}
java> java -cp dest aoptest.Main
aaa
注意: interface の場合 には、実際には private でないことに注意:
public class Main implements MainInterface {

	public static void main(String[] args) {

		System.out.println( new Main().str ); // ok
	}
}
もし、抽象クラスに対してなら、コンパイルエラーとなる:
public abstract class AbstractMain { }
public class Main extends AbstractMain {

	public static void main(String[] args) {

		System.out.println( new Main().str ); // コンパイルエラー
	}
}
public aspect MainAspect {

	private String AbstractMain.str = "aaa";
}

メソッドの Introduction

メソッドの Introduction - その 1

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {
		new Main().method();
	}
}
public aspect MainAspect {

	public void Main.method() {
		System.out.println("method");
	}
}
java> java -cp dest aoptest.Main
method

メソッドの Introduction - その 2

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {
		new Main().method(); // コンパイルエラー
		                      // Introduction されたメソッドは
		                      // public でない。
	}
}
public aspect MainAspect {

	private void Main.method() { // MainAspect 内のみで呼び出すことができる。
	                              // したがって上記の Main クラス内での
	                              // このメソッドの呼び出しはコンパイルエラー
		System.out.println("method");
	}
}

メソッドの Introduction - その 3

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {
		new Main();
	}
}
public aspect MainAspect {

	private void Main.method() {
		System.out.println("method");
	}

	after() returning(Main main) : call( Main.new() ) {
		main.method();
	}
}
java> java -cp dest aoptest.Main
method

メソッドの Introduction - その 4

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {
		new Main().method();
	}
}
public aspect MainAspect {

	public void MainInterface.method() {
		System.out.println("method");
	}
}
java> java -cp dest aoptest.Main
method

メソッドの Introduction - その 5

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {
		new Main();
	}
}
public aspect MainAspect {

	after() returning(Main main) : call( Main.new() ) {
		main.method();
	}

	private void MainInterface.method() {
		System.out.println("method");
	}
}
java> java -cp dest aoptest.Main
method

メソッドの Introduction - その 6

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {
		new Main();
	}
}
public aspect MainAspect {

	public abstract void MainInterface.method();
}
java> java -cp dest aoptest.Main

メソッドの Introduction - その 7

(1.1rc1 OK)

public interface MainInterface { }
public class Main implements MainInterface {

	public static void main(String[] args) {
		new Main().method();
	}
}
public aspect MainAspect {

	public abstract void MainInterface.method();
}
// 横に長いので改行しています (改行を \ マークで表しています)

java> java -cp dest aoptest.Main
Exception in thread "main" java.lang.AbstractMethodError: aoptest.Main.method()V
        at aoptest.MainAspect.ajc$interMethodDispatch1$aoptest_MainAspect \
        $aoptest_MainInterface$method(MainAspect.java)
        at aoptest.Main.main(Main.java:8)
もし MainInterface interface で参照して method() を呼び出しても実行結果は同じ:
public class Main implements MainInterface {

	public static void main(String[] args) {
		MainInterface main = new Main();
		main.method();
	}
}

メソッドの Introduction - その 8

(1.1rc1 OK)

public abstract class AbstractMain { }
public class Main extends AbstractMain {

	public static void main(String[] args) {
		new Main();
	}
}
public aspect MainAspect {

	public abstract void AbstractMain.method();
}
java> java -cp dest aoptest.Main

メソッドの Introduction - その 9

(1.1rc1 OK)

public abstract class AbstractMain { }
public class Main extends AbstractMain {

	public static void main(String[] args) {
		new Main().method();
	}
}
public aspect MainAspect {

	public abstract void AbstractMain.method();
}
// 横に長いので改行しています (改行を \ マークで表しています)

java> java -cp dest aoptest.Main
Exception in thread "main" java.lang.AbstractMethodError: aoptest.AbstractMain.method()V
        at aoptest.MainAspect.ajc$interMethodDispatch1$aoptest_MainAspect \
        $aoptest_AbstractMain$method(MainAspect.java)
        at aoptest.Main.main(Main.java:8)
AbstractMain クラスの型でオブジェクトを参照して method() メソッドを呼び出しても実行結果は同じ:
public class Main extends AbstractMain {

	public static void main(String[] args) {
		AbstractMain main = new Main();
		main.method();
	}
}

メソッドの Introduction - その 10 : static メソッド

(1.1rc1 OK)

public interface MyInterface { }
public class Main {

	public static void main(String[] args) {
		MyInterface.method();
	}
}
public aspect MainAspect {

	public static void MyInterface.method() {
		System.out.println("method");
	}
}
// 横に長いので改行しています (改行を \ マークで表しています)

java> java -cp dest aoptest.Main
Exception in thread "main" java.lang.VerifyError: \
(class: aoptest/MainAspect, method:ajc$interMethodDispatch1$aoptest_MainAspect \
$aoptest_MyInterface$method signature: ()V) Illegal type in constant pool
        at aoptest.Main.main(Main.java:8)

メソッドの Introduction - その 11 : static メソッド

(1.1rc1 OK)

public abstract class MyAbstractClass { }
public class Main {

	public static void main(String[] args) {
		MyAbstractClass.method();
	}
}
public aspect MainAspect {

	public static void MyAbstractClass.method() {
		System.out.println("method");
	}
}
java> java -cp dest aoptest.Main
method

メソッドの Introduction - その 12

(1.1rc1 OK)

public class Main {

	private String str;

	public Main(String str) {
		this.str = str;
	}

	public static void main(String[] args) {
		new Main("aaa").setString("bbb");
	}
}
public aspect MainAspect {

	public void Main.setString(String str) {
		this.str = str; // str は private としとて宣言されているので
		                  // アスペクトからはアクセスできない。
		                  // したがって、コンパイルエラー
	}
}
privileged の使用:
public class Main { // 変更なし

	private String str;

	public Main(String str) {
		this.str = str;
	}

	public static void main(String[] args) {
		new Main("aaa").setString("bbb");
	}
}
privileged aspect MainAspect {

	public void Main.setString(String str) {
		this.str = str; // ok
	}
}

コンストラクタの Introduction - その 1

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {
		new Main("aaa");
	}
}
public aspect MainAspect {

	public Main.new(String str) {
		System.out.println(str);
	}
}
java> java -cp dest aoptest.Main
aaa

interface の Introduction - その 1

(1.1rc1 OK)

public interface MainInterface { }
public class Main {

	public static void main(String[] args) {
		MainInterface main = new Main();
	}
}
public aspect MainAspect {

	declare parents: Main implements MainInterface;
}

interface の Introduction - その 2

(1.1rc1 OK)

public interface MainInterface { }
public class YourMain { }
public class Main {

	public static void main(String[] args) {

		MainInterface main1 = new Main();
		MainInterface main2 = new YourMain();
	}
}
public aspect MainAspect {

	declare parents: Main || YourMain implements MainInterface;
}

interface の Introduction - その 3

(1.1rc1 OK)

public class Main {

	public static void main(String[] args) {

		Main main = new Main();

		Cloneable cloneable        = main;
		Serializable serializable = main;
	}
}
public aspect MainAspect {

	declare parents: Main implements Serializable, Cloneable;
}

interface の Introduction - その 4

(1.1rc1 OK)

public class YourMain { }
public class Main {

	public static void main(String[] args) {

		Cloneable main1 = new Main();
		Cloneable main2 = new YourMain();
	}
}
public aspect MainAspect {

	declare parents: aoptest.* implements Cloneable;
}

interface の Introduction - その 5

(1.1rc1 OK)

public class YourMain { }
public class Main {

	public static void main(String[] args) {

		List list1 = Arrays.asList( Main.class.getInterfaces() );
		List list2 = Arrays.asList( YourMain.class.getInterfaces() );

		System.out.println("Main     : " + list1 );
		System.out.println("YourMain : " + list2 );
	}
}
public aspect MainAspect {

	private interface MainInterface { }

	declare parents: (aoptest.* && YourMain) implements Cloneable;
}
java> java -cp dest aoptest.Main
Main     : []
YourMain : [interface java.lang.Cloneable]

interface の Introduction - その 6

(1.1rc1 OK)

public class YourMain implements Serializable { }
public class Main {

	public static void main(String[] args) {

		List list1 = Arrays.asList( Main.class.getInterfaces() );
		List list2 = Arrays.asList( YourMain.class.getInterfaces() );

		System.out.println( list1 );
		System.out.println( list2 );
	}
}
public aspect MainAspect {

	declare parents: (aoptest.* && Serializable+) implements Cloneable;
}
java> java -cp dest aoptest.Main
Main     : []
YourMain : [interface java.io.Serializable, interface java.lang.Cloneable]

継承の Introduction - その 1

(1.1rc1 OK)

public abstract class AbstractMain { } // もちろん、抽象クラスじゃなくて、普通のクラスでも OK
public class Main {

	public static void main(String[] args) {

		AbstractMain main = new Main();
	}
}
public aspect MainAspect {

	declare parents: Main extends AbstractMain;
}

[
TOP ]

更新履歴

todo