关于Java内部类字段和方法不能使用static修饰的缘由

昨天的文章中,遗留了一个问题就是,为何Java内部类字段和方法不能使用static修饰。java

先下下面一段代码:jvm

class OuterClass {

 public int age=20; 
 
 class InnerClass {
  static int i = 100; // compile error
  static void f() { } // compile error
 }
}

上面的内部类的成员变量和方法,只要加上了static修饰,就会出现编译错误。学习

缘由:code

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

看下面一个例子:内存

class Employee {
    public String name;
}

上面是一个成员变量,如今咱们建立两个实例并赋值:虚拟机

Employee a = new Employee(); 
a.name = "Oscar";

Employee b = new Employee();
b.name = "jcyang";

上面的代码是没问题的。编译

ok,如今继续看,假如咱们容许内部类出现静态成员,会出现什么状况:class

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语言在语义层面不容许咱们那么作,这其实不是技术问题,是一个语言的逻辑和语义问题。

最后欢迎加入个人知识星球,一块儿学习。 image

相关文章
相关标签/搜索