看板 java 關於我們 聯絡資訊
※ 引述《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
lachtchlee:你這個Outer.java根本通不過編譯器那一關 是不是 ? 08/23 22:29
mars90226:因為就不允許了不是嗎? 08/23 22:47
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)
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)
lachtchlee:因為VERSION始終指向同一個位址 08/23 23:18
lachtchlee:你很用功佩服Java Rules Douglas Dunn Addison-Wesley 08/23 23:22
lachtchlee:2002 一書 有相關資料 有性趣的話 不仿瞧瞧 good luck 08/23 23:27
sbrhsieh:哪方面的資料? 08/23 23:29
lachtchlee:興趣 08/23 23:30
lachtchlee:something about static & inner class 08/23 23:32
sbrhsieh:為甚麼我需要看這些資料?我到覺得你比較需要多多研究 08/23 23:37
lachtchlee:你太自大了 08/23 23:48
sbrhsieh:不敢,這方面還不如你。 08/23 23:52
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)
leeyh:我覺得你說法有點奇怪, 這是語法上面不允許的 08/25 22:11
leeyh:這跟VM能不能執行這種概念, 有沒有缺失完全是兩回事 08/25 22:14
sbrhsieh:我是提出來反對"因為效率上的考量而禁止"這個觀點 08/25 23:11
tomap41017:原PO最後一段有清楚說明為何要這樣寫的理由,但你 08/26 23:05