成员内部类为什么不能定义静态属性和静态方法

根据成员内部类的定义:

  1. 首先生成外部类的实例对象
  2. 然后生成绑定到外部类实例对象的成员内部类实例对象

外部类实例对象的生成一定要先于成员内部类实例对象的生成

public class InnerClassDemo{
     //对于final修饰的成员变量,说明该变量是只读变量,只能进行一次赋值操作,只能存在以下两种赋值情况,在这两个地方我们必须给它们赋初值。
     //1)声明该成员变量时赋值:
     //  a)如果表达式的值是常量表达式(返回基本类型数据),则编译器编译时就计算出该表达式的值,知道该值,那么编译器就可能会在编译时期优化程序
     //  b)如果不是常量表达式(返回引用类型数据),则编译器编译时,就不知道该值。
     //2)在构造方法中赋值,运行时赋值,则编译器编译时,就不知道该值

     //实例成员被默认初始化为0
     int x;

     //static final修饰的变量必须被显示初始化,要么在声明时赋值初始化,要么在静态块中初始化。
     //否则,语法错误
     static final int i;
     static int y;//可以不用初始化,系统会默认赋值0
     static final int j=2;
     //静态块,当类被JVM加载到内存时,静态块的静态代码执行。
     static{
          i=1;
          System.out.println("i="+i);
          System.out.println("j="+j);
      }

      public static void main(String[] args){
          InnerClassDemo innerclassdemo=new InnerClassDemo();
          InnerClass innerClass=innerclassdemo.new InnerClass();
          System.out.println("innerclassdemo中x和y的默认值分别是是:"+innerclassdemo.x+y);
          System.out.println("innerClass中i="+innerClass.i);
  System.out.println("innerClass中str="+innerClass.str);
          System.out.println("Welcome!");
      }

class InnerClass{
      //1.在成员内部类中,只有编译器在编译的时候赋值号右边是常量表达式(编译时,可以计算出表达式的基本类型值),
      //左边是只读静态常量的情况才可以存在静态只读常量
      //然后编译器把它当做编译器常量来使用,其实说白了就是和这个外部类的实例无关。
      static final int i=50;
      static final String str='s';

     //2.以下均不可以
     //2.1虽然static final为只读静态变量,但是是在构造方法中运行时赋值,编译时不知道其值。
     //static final int i;
     //static final String str
     //2.2虽然static final为只读静态变量,但是赋值号右边不是常量表达式(返回引用类型数据),编译时并不知道其引用的实例值。
     //static final String str=new String("");

     //3.没有外部类实例,此内部类不需要外部类实例就初始化了变量,与成员内部类的定义相悖。
     //static InnerClass innerClass=new InnerClass();

    //4.静态方法中,但是没有外部类实例
    //static void method(){
    //     InnerClass innerClass=new InnerClass();
    //    }

 

综上,其实内部类并不是完全不能出现static这样的修饰的,只要符合第一种情况的就是可以的。

编译器其实无法区分第二种,第三种情况的,第三种的情况肯定是不行的与内部成员类的定义相驳,所以第二种情况在语法上也被禁止了。

第三种情况,根据初始化的流程我们知道,在类加载的时候,static变量就必须被显式初始化,那么我们InnerClass成员内部类的实例对象在没InnerClassDemo外部类的实例对象的时候便生成了。这样这个成员内部类就脱离了外部类的掌控,不需要外部类的对象就可以生成内部类的对象,这与成员内部类的定义就相驳了,因为我们知道成员内部类的对象必须是先有外部类的对象才能创建,成员内部类的对象 脱离了其外部类的对象 就不会存在,并且是绑定在一起的,所以成员内部类不可以定义静态变量。

第四种情况与第三种情况相同原因。

程序运行结果:
在这里插入图片描述

成员内部类是在类的内部方法的外部编写的类。它的特点是可以访问外部类的所有成员(包括私有成员),并且需要通过创建外部类对象来访问。 在外部类中,可以通过直接创建内部类的对象来访问内部类属性和方法,就像访问普通的类一样。但是需要注意的是,在外部类的静态成员不能使用非静态成员内部类静态内部类定义在外部类中的静态成员。它的特点是不依赖于外部类的实例而存在,可以直接创建静态内部类的对象来访问它的属性和方法。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。 局部内部类定义在方法内部的类。它的特点是只能在方法内部使用,并且只有在方法内部创建对象后才能访问局部内部类属性和方法。局部内部类可以访问外部类的所有成员,包括私有成员。 匿名内部类是没有类名的内部类。它的定义格式比较特殊,通常用于实现接口或继承父类,并重写其方法。匿名内部类的特点是只能创建一个对象,并且只能在声明的地方使用。 总结: - 成员内部类是在外部类的方法外部定义的类,可以访问外部类的所有成员。 - 静态内部类是在外部类中定义静态成员,不依赖于外部类的实例。 - 局部内部类定义在方法内部的类,只能在方法内部使用。 - 匿名内部类是没有类名的内部类,通常用于实现接口或继承父类,并重写其方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java内部类详解(含:成员内部类、局部内部类、匿名内部类静态内部类)](https://blog.csdn.net/leaf__yang/article/details/126221094)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Java成员内部类静态内部类、局部内部类、匿名内部类详解](https://blog.csdn.net/sun10367/article/details/108050807)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值