作者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