Discussion:
[問題]inner class存取其外部成員的問題
(时间太久无法回复)
shen
2007-07-03 18:18:56 UTC
Permalink
大家好
小弟在練習使用匿名的inner class的時候遇到了點問題
請大家指點迷津一下

當我在inner class中去存取其外部class的某個reference時
若這個reference在外部class的建構式中去宣告,那編譯時就會出現錯誤訊息
訊息內容是cannot find symbol,而該symbol就是指那個reference
程式碼的大略示意圖如下:

public class OuterClass {

public OuterClass() {
ClassA refA = new ClassA(); //ClassA有一個我想用到的methodA
}

InnerClass inner = new InnerClass() {
public void innerMethod() {
refA.methodA //此處發生編譯錯誤:cannot find symbol,symbol:varible refA
}
};
}
===========================換個方法===================================

但是,假如我在建構式之外先宣告refA,進了建構式再進一步將它指派給ClassA,
此時就可通過編譯
程式碼的大略示意圖如下:

public class OuterClass {

ClassA refA;
public OuterClass() {
refA = new ClassA(); //ClassA有一個我想用到的methodA
}

InnerClass inner = new InnerClass() {
public void innerMethod() {
refA.methodA //這一次通過編繹了,why??
}
};
}

想請教各位,為什麼我在建構式之外先宣告過,就不會編譯錯誤了呢??
或是請大家指點我一下,該去查什麼相關的資料,可以解釋這個現象呢??
謝謝各位~

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.129.62.37
※ 編輯: losesong 來自: 140.129.62.37 (07/04 02:18)
淺水中
2007-07-04 00:21:28 UTC
Permalink
※ 引述《losesong (shen)》之銘言:
: 大家好
: 小弟在練習使用匿名的inner class的時候遇到了點問題
: 請大家指點迷津一下
: 當我在inner class中去存取其外部class的某個field時
: 若這個field在外部class的建構式中才去宣告,那編譯時就會出現錯誤訊息
: 訊息內容是cannot find symbol,而該symbol就是指那個field
: 程式碼的大略示意圖如下:
: public class OuterClass {
: public OuterClass() {
: ClassA refA = new ClassA(); //ClassA有一個我想用到的methodA
: }
: InnerClass inner = new InnerClass() {
: public void innerMethod() {
: refA.methodA(); //此處發生編譯錯誤:cannot find symbol,symbol:varible refA
: }
: };
: }
: ===========================換個方法===================================
: 但是,假如我在建構式之外先宣告refA,進了建構式再進一步將它指派給ClassA,
: 此時就可通過編譯
: 程式碼的大略示意圖如下:
: public class OuterClass {
: ClassA refA;
: public OuterClass() {
: refA = new ClassA(); //ClassA有一個我想用到的methodA
: }
: InnerClass inner = new InnerClass() {
: public void innerMethod() {
: refA.methodA(); //這一次通過編繹了,why??
: }
: };
: }
: 想請教各位,為什麼我在建構式之外先宣告過,就不會編譯錯誤了呢??
: 或是請大家指點我一下,該去查什麼相關的資料,可以解釋這個現象呢??
: 謝謝各位~
這個是scope的問題
外層的block宣告的變數可以給內層的block用
同層的block內的變數不能互用.
例如:
{
int a=0;
{
a=1; //ok
}
}
------------------
{
int a=0;
}

{
a = 1; //error cannot find the symbol
}




--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.123.105.36
shen
2007-07-04 08:48:44 UTC
Permalink
※ 引述《calais007 (淺水中)》之銘言:
: ※ 引述《losesong (shen)》之銘言:
: : 大家好
: : 小弟在練習使用匿名的inner class的時候遇到了點問題
: : 請大家指點迷津一下
: : 當我在inner class中去存取其外部class的某個field時
: : 若這個field在外部class的建構式中才去宣告,那編譯時就會出現錯誤訊息
: : 訊息內容是cannot find symbol,而該symbol就是指那個field
: : 程式碼的大略示意圖如下:
: : public class OuterClass {
: : public OuterClass() {
: : ClassA refA = new ClassA(); //ClassA有一個我想用到的methodA
: : }
: : InnerClass inner = new InnerClass() {
: : public void innerMethod() {
: : refA.methodA(); //此處發生編譯錯誤:cannot find symbol,symbol:varible refA
: : }
: : };
: : }
: : ===========================換個方法===================================
: : 但是,假如我在建構式之外先宣告refA,進了建構式再進一步將它指派給ClassA,
: : 此時就可通過編譯
: : 程式碼的大略示意圖如下:
: : public class OuterClass {
: : ClassA refA;
: : public OuterClass() {
: : refA = new ClassA(); //ClassA有一個我想用到的methodA
: : }
: : InnerClass inner = new InnerClass() {
: : public void innerMethod() {
: : refA.methodA(); //這一次通過編繹了,why??
: : }
: : };
: : }
: : 想請教各位,為什麼我在建構式之外先宣告過,就不會編譯錯誤了呢??
: : 或是請大家指點我一下,該去查什麼相關的資料,可以解釋這個現象呢??
: : 謝謝各位~
: 這個是scope的問題
: 外層的block宣告的變數可以給內層的block用
: 同層的block內的變數不能互用.
:

謝謝你的回答
但是我覺得這樣解釋好像怪怪的
因為我的問題是出在:refA如果到了建構式才去宣告並指派一個物件給它
這樣情況下,內部類別去存取refA才會出現compile error

或者calais板友的意思是說,inner class已經視為另一塊block,所以才會不能取用??
但是我看書上是說,inner class(非static),可以存取外部class的成員
似乎跟block沒有關係??

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.129.62.37
※ 編輯: losesong 來自: 140.129.62.37 (07/04 16:46)
※ 編輯: losesong 來自: 140.129.62.37 (07/04 16:48)
godfat 真常
2007-07-04 10:33:24 UTC
Permalink
我覺得 java 的 inner class 滿有趣的,所以稍微看了一下你的問題
基本上﹍

※ 引述《losesong (shen)》之銘言:
: ※ 引述《calais007 (淺水中)》之銘言:
: : 這個是scope的問題
: : 外層的block宣告的變數可以給內層的block用
: : 同層的block內的變數不能互用.

that's right.

: 謝謝你的回答
: 但是我覺得這樣解釋好像怪怪的

你的問題的答案就是上面那樣,跟 inner class 沒有關係。
你原先的寫法 refA 是在 constructor (後面以 c'tor 稱之) 裡面才可取用。
簡單地說就是 local variable

此外,inner class 寫法錯誤﹍
要這樣寫:

class O{
class I{
}
}

建議你重看一下 scope 的觀念再看 inner class

: 但是我看書上是說,inner class(非static),可以存取外部class的成員
: 似乎跟block沒有關係??

true.
所以說你的問題跟 inner class 無關,先確認你的 scope 觀念正確,例如:

class C{
int i;
C(int i){
int j = i + this.i;
}
}

哪個 i 是哪個 i ?

--
「行!Loki!」(rocky )

-Gurumin  王子? XD

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.228.88.200
c***@kkcity.com.tw
2007-07-04 10:34:32 UTC
Permalink
Post by shen
※ 引述《calais007 (淺水中)》之銘言:
: 這個是scope的問題
: 外層的block宣告的變數可以給內層的block用
: 同層的block內的變數不能互用.
謝謝你的回答
但是我覺得這樣解釋好像怪怪的
因為我的問題是出在:refA如果到了建構式才去宣告並指派一個物件給它
這樣情況下,內部類別去存取refA才會出現compile error
或者calais板友的意思是說,inner class已經視為另一塊block,所以才會不能取用??
但是我看書上是說,inner class(非static),可以存取外部class的成員
似乎跟block沒有關係??
就如同calais007大大所說的,你的refA這個物件參考變數是宣告在建構子裡,
那麼在建構子結束後,變數也會跟著消失,如何能在別的地方取用呢?
而"內部類別可以取用外部class成員"這句話,是指直接宣告在class下的成員
,所以當你將refA這個變數宣告在class下,就可以取用,所以編譯當然就ok


--
┌─────◆KKCITY◆─────┐ ◢╱ 只要你通過身份認證 ~ ◥█
│ bbs.kkcity.com.tw │ █▉─ 免經驗、五人連署即開班系板 ◥
└──《From:61.216.167.50 》──┘ ◥╲ 趕快為班上設個秘密基地吧! ◢
--
我開始困惑了
2007-07-04 15:38:01 UTC
Permalink
※ 引述《losesong (shen)》之銘言:
: 大家好
: 小弟在練習使用匿名的inner class的時候遇到了點問題
: 請大家指點迷津一下
: 當我在inner class中去存取其外部class的某個field時
: 若這個field在外部class的建構式中才去宣告,那編譯時就會出現錯誤訊息
: 訊息內容是cannot find symbol,而該symbol就是指那個field
: 程式碼的大略示意圖如下:
: public class OuterClass {
: public OuterClass() {
: ClassA refA = new ClassA(); //ClassA有一個我想用到的methodA
: }
: InnerClass inner = new InnerClass() {
: public void innerMethod() {
: refA.methodA(); //此處發生編譯錯誤:cannot find symbol,symbol:varible refA
: }
: };
: }
: ===========================換個方法===================================
: 但是,假如我在建構式之外先宣告refA,進了建構式再進一步將它指派給ClassA,
: 此時就可通過編譯
: 程式碼的大略示意圖如下:
: public class OuterClass {
: ClassA refA;
: public OuterClass() {
: refA = new ClassA(); //ClassA有一個我想用到的methodA
: }
: InnerClass inner = new InnerClass() {
: public void innerMethod() {
: refA.methodA(); //這一次通過編繹了,why??
: }
: };
: }
: 想請教各位,為什麼我在建構式之外先宣告過,就不會編譯錯誤了呢??
: 或是請大家指點我一下,該去查什麼相關的資料,可以解釋這個現象呢??
: 謝謝各位~

用heap來解釋不曉得通不通......(解釋錯誤請見諒.....)

↑運算元
↑動態變數
↑建構子
↑靜態變數

所以在heap中擺放順序是
ClassA refA
建構子指定 refA instance
動態變數 Inner Class
運算元

不知道這樣子通否?

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.232.237.53
Alien
2007-07-05 02:55:09 UTC
Permalink
※ 引述《losesong (shen)》之銘言:
: 大家好
: 小弟在練習使用匿名的inner class的時候遇到了點問題
: 請大家指點迷津一下
: 當我在inner class中去存取其外部class的某個field時
: 若這個field在外部class的建構式中才去宣告,那編譯時就會出現錯誤訊息
: 訊息內容是cannot find symbol,而該symbol就是指那個field
: 程式碼的大略示意圖如下:
: public class OuterClass {
: public OuterClass() {
: ClassA refA = new ClassA(); //ClassA有一個我想用到的methodA
: }
: InnerClass inner = new InnerClass() {
: public void innerMethod() {
: refA.methodA(); //此處發生編譯錯誤:cannot find symbol,symbol:varible refA
: }
: };
: }


簡單來說, 第一個例子的 fieldA 根本就不是 OuterClass
的 member field. 既不是一個 member field, inner class
又怎可能存取得到?

Alien

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 202.72.0.45

Loading...