匿名の内部クラスは外のクラスを使うなぜfinal型を使うのか
5332 ワード
では、コアの問題は、「レプリカ」へのアクセスと、実際の元のローカル変数へのアクセスとの意味効果が同じになるようにするにはどうすればいいのでしょうか.変数がfinalの場合、基本データ型の場合、その値は変わらないため、その複製品は元の量と同じである.意味効果は同じです.(finalでない場合、コピーが元の変数と一致することは保証されません.なぜなら、メソッドでは元の変数に変更され、ローカル内部クラスではコピーに変更されます)変数がfinalの場合、参照タイプの場合、参照値が変わらない(すなわち、同じオブジェクトを永遠に指す)ため、コピーは元の参照変数と同じです.常に同じオブジェクト(finalであるため、このオブジェクトのみを指すことが保証され、他のオブジェクトを指すことができない)を指し、局所内部クラスでアクセスするレプリカとメソッドコードでアクセスする元のオブジェクトは、永遠に同じである、すなわち、意味効果は同じである.そうでない場合、メソッドで元の変数を変更し、ローカル内部クラスでコピーを変更する場合、コピーと元の変数が一致することは保証されません(したがって、元は同じ変数であるべきです).一言:この規定は仕方がない.プログラム設計言語の設計は実現技術の制限を受けることも説明する.これが一例です.なぜなら、私は多くの人がこのような観点を持っているのを見ています:設計と考えは最も重要で、実現の技術は重要ではありません.あなたが設計と規定をすれば、すべて実現することができます.
次に、ABSClassを匿名で呼び出す方法の例を実装します.
public static void test(final String s){
ABSClass c = new ABSClass(){
public void m(){
int x = s.hashCode();
System.out.println(x);
}
};
// .
}
コードから見ると、1つのメソッドの内部で定義された内部クラスのメソッドが外部メソッド内のローカル変数またはメソッドパラメータにアクセスするのは自然なことですが、内部クラスがコンパイルされるときにどのようにこの変数を取得するかは、内部クラスがそのライフサイクルを除いてメソッドの内部にあるため、他の面では一般的なクラスです.では、その外のローカル変数やメソッドパラメータはどのように内部クラスにアクセスされますか?コンパイラは実装時に実際には次のようになります.
なぜ匿名の内部クラスとローカルの内部クラスはfinal変数にしかアクセスできないのか
匿名の内部クラスがメソッドの内部に現れるため、変数の役割ドメインの問題です.このメソッドのパラメータまたはメソッドで定義された変数にアクセスする場合は、これらのパラメータと変数をfinalに修飾する必要があります.匿名の内部クラスはメソッドの内部にあるが、実際にコンパイルする場合、内部クラスはOuterにコンパイルされるからである.Inner,これは内部クラスの位置と外部クラスのメソッドが同じレベルにあることを示し,外部クラスのメソッドの変数またはパラメータはメソッドの局所変数にすぎず,これらの変数またはパラメータの役割ドメインはこのメソッドの内部でのみ有効である.コンパイル時に内部クラスとメソッドが同じレベルにあるため、メソッドの変数やパラメータはfinalであり、内部クラスのみ参照できます.
Javaコード:
public class MyClass {
public MyClass() {
final int finalValue = 10;
int not$Final = 20;
MyInterface myInterface = new MyInterface() {
public void functionWithoutPara() {
//compile Error
//System.out.println(noFinal);
System.out.println(finalValue);
}
public void functionWithPara(int num) {
System.out.println("The parameter " + num
+ " has been passed by the method");
}
};
myInterface.functionWithoutPara();
myInterface.functionWithPara(not$Final);
System.out.println(myInterface.getClass().getName());
}
public static void main(String[] args) {
new MyClass();
}
}
二、なぜローカル内部クラスはfinal変数にしかアクセスできないのか
簡単に言えば、役割ドメインの問題です.メソッドの外でやっていることは、メソッド内で定義された変数を変えることはできません.メソッドの中にこの時点でこの局所変数が存在しているかどうか分からないからです.この内部クラスではメソッド内のローカル変数は失効し,すなわち役割ドメイン内にないためアクセスできない.
しかしなぜここはfinalでアクセスできるのでしょうか?Javaはcopy->local->variableという方法で実現されているため、finalと定義されたローカル変数をコピーして使用し、参照したものも持ってきて使用することができますが、再割り当てはできません.これによりaccess->local->variableという仮象ができますが、この場合は再付与できないため、予想できないことは起こりません
三、ローカル内部クラスを定義し、ローカル内部クラスが外部で定義されたオブジェクトを使用している場合、コンパイラはパラメータ参照がfinalであることを要求するのはなぜですか.注:匿名の内部クラスを含むローカル内部クラス.
理由は次のとおりです.
abstract class ABSClass{
public abstract void print();
public class Test2{
public static void test(final String s){// , final
ABSClass c=new ABSClass(){
public void print(){
System.out.println(s);
}
};
c.print();
}
public static void main(String[] args){
test("Hello World!");
}
}
}