鱼C论坛

 找回密码
 立即注册
查看: 4935|回复: 3

[好文转载] 关于 Java 内部类字段和方法不能使用 static 修饰的原因

[复制链接]
发表于 2021-7-12 20:36:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
为什么 Java 内部类字段和方法不能使用 static 修饰?
先看下面一段代码:
class OuterClass {
 
 public int age=20; 
 
 class InnerClass {
  static int i = 100; // compile error
  static void f() { } // compile error
 }
} 
上面的内部类的成员变量和方法,只要加上了 static 修饰,就会出现编译错误。

原因:

简单的来说,内部类是外部类的实例,与外部类的的成员变量是一样的,每个实例化出来的对象,它的成员变量赋值都是独立的不会相互影响。

看下面一个例子:
class Employee {
    public String name;
}
上面是一个成员变量,现在我们创建两个实例并赋值:
Employee a = new Employee(); 
a.name = "Oscar";
 
Employee b = new Employee();
b.name = "jcyang";
上面的代码是没问题的。

ok,现在继续看,假如我们允许内部类出现静态成员,会出现什么情况:
class Employee {
    public String name;
    class InnerData {
       public static count; // ??? count of which ? a or b? 
     }
}
这个时候,我们给内部类实例的静态字段 count 赋值,就会发生混乱:
Employee a = new Employee(); 
a.name = "Oscar";
a.new InnerData().count=3
 
Employee b = new Employee();
b.name = "jcyang";
b.new InnerData().count=4 
现在已经分不清到底是修改类 count 字段,逻辑上来说成员变量是对象各自独立的属性读写都是不依赖的,但如果上面的场景成立,就会自相矛盾。所以这就是为什么内部类里面不允许存在静态成员的原因。

其实归根结底,还是类与对象的区别,静态属性不依赖于对象,因为它保存在 jvm 的静态区,所以访问修改的时候不需要依赖当前有没有存活的对象,在虚拟机加载的时候也是优先于实例生成的。而实例对象则是保存在 jvm 的堆内存中,想要访问内部类,必须先实例化外部类,然后通过外部类才能访问内部类。内部类其实也可以认为是外部类的一个成员变量,只要是成员变量,各个对象都是不依赖的,静态属性的出现破坏了这一逻辑,所以 java 语言在语义层面不允许我们那么做,这其实不是技术问题,是一个语言的逻辑和语义问题。

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-12 21:11:45 | 显示全部楼层
跟C++不一样呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-7-13 07:32:42 | 显示全部楼层

是有一些不一样

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-13 08:44:17 | 显示全部楼层
这么理解:内部类是依赖于当前对象存在的,是对象一级的,不是类一级的,所以可以认为是一个变量。
然后想问一下:静态内部类里面的属性可以是静态的么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 18:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表