作者sbrhsieh (偶爾想擺爛一下)
看板java
標題Re: [問題] 一般內部類別不能放靜態成員?
時間Tue Aug 23 22:04:57 2011
※ 引述《exorpo (exorpo)》之銘言:
: 標題: [問題] 一般內部類別不能放靜態方法?
: 時間: Mon Aug 22 18:39:19 2011
:
: 大家好!最近在學Java的內部類別,碰到了一點問題...
:
: 想請問一般內部類別裡面不能放靜態(static)成員嗎?
:
: 如下方程式碼編譯是不通過的。
:
: public class Test {
: public static void fun() {} // OK
: public class TestInner {
: static int x; // not OK
: public static void fun() {} // not OK
: }
: }
:
: 想知道原因
:
: 謝謝大家!
:
: --
:
※ 發信站: 批踢踢實業坊(ptt.cc)
: ◆ From: 111.248.226.136
: ※ 編輯: exorpo 來自: 111.248.226.136 (08/22 18:42)
: ※ 編輯: exorpo 來自: 111.248.226.136 (08/22 18:42)
: → pico2k:原因就是Java不允許這樣子的宣告。 08/22 19:26
: → pico2k:請去看一下Java Language Specification 08/22 19:31
: → exorpo:嗯,找到了,謝謝!:) Ans:http://goo.gl/6zIzQ 08/22 19:55
: 推 po500922:宣告成static代表他不屬於單一個物件~應該是這樣吧 08/22 20:57
: 推 LaPass:C 好像才能這樣玩 java不行 08/23 07:58
: 推 LaPass:眼殘看錯,我看成在fun內宣告static 08/23 08:01
: 推 lachtchlee:static variable 好比愛心雨傘 放在店家門口(外部類中 08/23 10:29
: → lachtchlee:非靜態內部類外)就可以了 何必把它們放在有保全的倉庫 08/23 10:34
: → lachtchlee:(非靜態內部類中) 本來用類的名稱就可拿到的愛心傘 還 08/23 10:39
: → lachtchlee:要請出外部類的實例 然後創建非靜態內部類的實例 才摸 08/23 10:44
: → lachtchlee:得到那把愛心傘 效率太差 故乾脆規定 在非靜態內部類 08/23 10:49
: → lachtchlee:中 不該出現static鼠輩 08/23 10:53
: → lachtchlee:static method也是鼠輩 08/23 10:55
: → sbrhsieh:跟效率無關。主要是語意上適不適當。 08/23 17:44
: 推 lachtchlee:有何根據@~@ 08/23 19:32
以下列 classes 來說:
package ptt.demo;
public class Outer {
public class Inner {
public static int instanceCount;
public Inner() {
++instanceCount;
}
}
}
任何 class 要 access instanceCount 這個 static field,只需要寫
ptt.demo.Outer.Inner.instanceCount(如同一般存取 static field 的寫法)。
這沒有牽涉到推文中提到的有關先建立 Outer instance 與 Outer.Inner instance,
再來 access instanceCount field 的這些步驟,所以不能以此推論為效率上的考量。
那我所稱是語意上適不適當部份,是指 instance inner class/nested class 在語意
上視為某個 object/instance 的 member(看看 Outer.Inner object 的建立方式:
someOuterObject.new Inner()),雖然它實際上是個 class,但應該不把它當作
一般的 class 對待。
這個主題在許多論壇應該都有討論過,有興趣者不妨 google 一下,看看各方的
觀點,看看自己認同哪一種。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.45.20.29
1F:推 lachtchlee:你這個Outer.java根本通不過編譯器那一關 是不是 ? 08/23 22:29
2F:→ mars90226:因為就不允許了不是嗎? 08/23 22:47
3F:推 lachtchlee:是的 08/23 22:50
OK,上面的 Outer 與 Outer.Inner classes 確實是可以存在的。
姑且不論你信不信,暫時把 Inner 改為
public class Outer {
public class Inner {
public static final String VERSION = "0.0.1";
public Inner() {
}
}
}
你可以透過 ptt.demo.Outer.Inner.VERSION 來 access 這個 static field(常數)。
※ 編輯: sbrhsieh 來自: 114.45.20.29 (08/23 22:57)
4F:推 lachtchlee:常量引用 可以 靜態變量則否 08/23 23:07
我覺得你要搞清楚,現在是討論為甚麼語法上做這樣的限制,不是編譯器說
不可以,然後由你來作結論"這是不可以的"。
我可以給你我一開始寫的那兩個 classes(Outer, Outer.Inner),不管你怎麼測試
與檢測,你會發現它的確就是如我所給的 source code。
http://www.megaupload.com/?d=0U670F9E
(ptt_demo.jar,裡頭包兩個 class file)
如果你懶得自己寫,可以直接 copy 這段碼回去與 ptt_demo.jar
一同編譯與執行。
package ptt.demo;
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
System.out.printf("[Before loop] Outer.Inner instance count: %s%n",
Outer.Inner.instanceCount);
for (int i = 0; i < 10; ++i) {
System.out.println(outer.new Inner());
}
System.out.printf("[After loop] Outer.Inner instance count: %s%n",
Outer.Inner.instanceCount);
}
}
※ 編輯: sbrhsieh 來自: 114.45.20.29 (08/23 23:17)
5F:→ lachtchlee:因為VERSION始終指向同一個位址 08/23 23:18
6F:→ lachtchlee:你很用功佩服Java Rules Douglas Dunn Addison-Wesley 08/23 23:22
7F:→ lachtchlee:2002 一書 有相關資料 有性趣的話 不仿瞧瞧 good luck 08/23 23:27
8F:→ sbrhsieh:哪方面的資料? 08/23 23:29
9F:→ lachtchlee:興趣 08/23 23:30
10F:→ lachtchlee:something about static & inner class 08/23 23:32
11F:→ sbrhsieh:為甚麼我需要看這些資料?我到覺得你比較需要多多研究 08/23 23:37
12F:推 lachtchlee:你太自大了 08/23 23:48
13F:→ sbrhsieh:不敢,這方面還不如你。 08/23 23:52
14F:→ sbrhsieh:抱歉。應該就事論事,希望你也做的到。 08/24 00:00
現實中,Java Language 的規範確是 non-static inner class 不能有 non-final
static field,但在 VM 層面是可以這麼做的,當我們這麼做了,沒有很明顯的
缺失(除了語意上妥當與否)。
※ 編輯: sbrhsieh 來自: 114.45.20.29 (08/24 00:25)
※ 編輯: sbrhsieh 來自: 114.45.20.29 (08/24 00:42)
15F:→ leeyh:我覺得你說法有點奇怪, 這是語法上面不允許的 08/25 22:11
16F:→ leeyh:這跟VM能不能執行這種概念, 有沒有缺失完全是兩回事 08/25 22:14
17F:→ sbrhsieh:我是提出來反對"因為效率上的考量而禁止"這個觀點 08/25 23:11
18F:推 tomap41017:原PO最後一段有清楚說明為何要這樣寫的理由,但你 08/26 23:05