文档章节

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

九劫散仙
 九劫散仙
发布于 2018/06/02 16:02
字数 635
阅读 27
收藏 7

昨天的文章中,遗留了一个问题就是,为什么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语言在语义层面不允许我们那么做,这其实不是技术问题,是一个语言的逻辑和语义问题。

最后欢迎加入我的知识星球,一起学习。 image

© 著作权归作者所有

九劫散仙
粉丝 268
博文 175
码字总数 189625
作品 0
海淀
私信 提问
Java成员内部类和静态内部类

Java成员内部类和静态内部类 使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。 在我们程...

秋风醉了
2014/07/11
65
0
new和反射产生java内部类的实例化详解

前两天看到一道口试题,是关于内部类的知识,觉得很有意思。 这道题是这样的: 根据注释填写(1),(2),(3)处的代码 public class Test{ ?????? public static void main(String[] args){ ??...

zaizai_loong
2013/09/02
3.5K
0
Java:关于Static静态关键字的那些小事

前言 在中,静态 关键字使用十分常见 本文全面 & 详细解析静态 关键字,希望你们会喜欢 目录 1. 定义 一种 表示静态属性的 关键字 / 修饰符 2. 作用 共用、共享 能有此作用的原因分析: Java...

Ala6
2018/10/27
0
0
关于Java对象的继承和多态学习笔记

-------------------------关于对象的构造过程------------------------ 如果类B继承了类A,那么当创建类B的实例时,遵循如下过程: 1、如果类A有静态的成员变量,初...

mj4738
2012/01/15
169
1
黑马程序员---面向对象之内部类

-------------------------android培训、java培训、期待与您交流! ------------------------- Java中的内部类有四种:一般内部类、静态内部类、局部内部类、匿名内部类。 一、一般内部类 定...

长平狐
2013/07/01
90
0

没有更多内容

加载失败,请刷新页面

加载更多

Android -------- kotlin插件神器Json直接生成javaBean

这是一个data class从JSON字符串生成Kotlin 的插件,换句话说,是一个将JSON字符串转换为Kotlin data class(Json到Kotlin)的插件 在使用Kotlin进行开发的时候,我们需要经常对Json数据做解析...

切切歆语
2分钟前
0
0
1、Spring注解开发,第一天

第一天:Spring annotation开发 目录:1、@Configuration与@Bean给容器注册组件 2、@ConponentScan自动扫描注解 一、@Configuration与@Bean给容器注册组件 1、旧版本中创建配置文件和Bean //...

有一个小阿飞
10分钟前
1
0
斯坦福博弈论笔记整理活动的任务已重新划分,望周知

参与方式:https://github.com/apachecn/stanford-game-theory-notes-zh/blob/master/CONTRIBUTING.md 整体进度:https://github.com/apachecn/stanford-game-theory-notes-zh/issues/1 项目......

ApacheCN_飞龙
11分钟前
3
0
使用HTML5 canvas完成的一个网页白板

该代码能够使用canvas对象完成的一个基本功能。仅供大家参考。 <html> <head> <meta http-equiv="Content-Type" contentType="text/html; charset=UTF-8" %> <title>Title</title> <script t......

前端老手
13分钟前
2
0
web漏洞之xss(学习记录)

xss又名跨站脚本攻击,是一种注入攻击,当web应用对用户输入过滤不严格,攻击者写入恶意的脚本代码(HTML、JavaScript)到网页中时,如果用户访问了含有恶意代码的页面,恶意脚本就会被浏览器...

半缘修道半缘君丶
15分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部