Last Updated : 2003/4/29
asato <asato@ncfreak.com>
[ TOP ]
注意
Introduction (Inter-type declarations)
フィールドの Introduction
参考ドキュメント
フィールドの Introduction - その 1
アスペクト内で 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
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
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 : 抽象クラスに対して
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
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 に対して
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
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
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
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
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
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
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
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
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
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
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 メソッド
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 メソッド
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
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
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
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
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
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
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
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
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
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
public abstract class YourClass { }
public class MyClass { public static class SubYourClass extends YourClass { public static void method() { // inter-dec でやると動作が違う System.out.println("MyClass.SubYourClass.method()"); } } }
public class Main { public static void main(String[] args) { YourClass.method(); MyClass.SubYourClass.method(); } }
public aspect MyAspect { public static void YourClass.method() { System.out.println("YourClass.method()"); } }