Re: [問題] 一般內部類別不能放靜態成員?
※ 引述《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
推
08/23 22:29, , 1F
08/23 22:29, 1F
→
08/23 22:47, , 2F
08/23 22:47, 2F
推
08/23 22:50, , 3F
08/23 22:50, 3F
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)
推
08/23 23:07, , 4F
08/23 23:07, 4F
我覺得你要搞清楚,現在是討論為甚麼語法上做這樣的限制,不是編譯器說
不可以,然後由你來作結論"這是不可以的"。
我可以給你我一開始寫的那兩個 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)
→
08/23 23:18, , 5F
08/23 23:18, 5F
→
08/23 23:22, , 6F
08/23 23:22, 6F
→
08/23 23:27, , 7F
08/23 23:27, 7F
→
08/23 23:29, , 8F
08/23 23:29, 8F
→
08/23 23:30, , 9F
08/23 23:30, 9F
→
08/23 23:32, , 10F
08/23 23:32, 10F
→
08/23 23:37, , 11F
08/23 23:37, 11F
推
08/23 23:48, , 12F
08/23 23:48, 12F
→
08/23 23:52, , 13F
08/23 23:52, 13F
→
08/24 00:00, , 14F
08/24 00:00, 14F
現實中,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)
→
08/25 22:11, , 15F
08/25 22:11, 15F
→
08/25 22:14, , 16F
08/25 22:14, 16F
→
08/25 23:11, , 17F
08/25 23:11, 17F
推
08/26 23:05, , 18F
08/26 23:05, 18F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):