内部类之成员内部类


一、位置

  成员内部类是最普通的内部类,它定义在一个类的内部

二、内部类的结构

  1.可以定义非静态属性和方法,不可以定义static修饰的属性和方法,可以定义static final修饰的编译期变量【不用加载类的字节码】

    1.1为什么不可以定义static修饰的属性和方法?

      首先内部类是外部类的一个成员,只有当外部类初始化的时候,内部类才能初始化,静态变量属于类级别,在类加载的时候就初始化,

        所以两者本身在语法上就有矛盾。

     1.2为什么可以定义static final修饰的变量?

      首先要先知道sttaic final修饰的变量叫做常量,常量分为编译期常量和非编译期常量

      编译期常量:在程序编译阶段【不需要加载类的字节码】,就可以确定常量的值

      非编译期常量:在程序运行阶段【需要加载类的字节码】,可以确定常量的值

    

public class OutterClass {
    
    class Inner{
        int a = 0;//非静态变量
        static int b = 0;//静态变量【报错!!】
        static final int c = 0;//编译期常量,不需要类加载
        static final Integer d = new Integer(2);//非编译期常量,需要类加载【报错!!】
    }
    
    public static void main(String[] args) {
        System.out.println(OutterClass.Inner.b);
        System.out.println(OutterClass.Inner.c);
        System.out.println(OutterClass.Inner.d);
    }

}

      b属性是静态的,它需要加载类的字节码Inner类,由于它是在OutterClass内部,需要外部类实例化才能加载,但是调用处没有实例化外部类,所以Inner也不会类加载,所以报错!!

      c属性是编译期常量,它不需要加载类的字节码Inner类,所以不会报错

      d属性是非编译期常量。它需要加载类的字节码Inner类,所以报错!!

  2.内部类可以被任何访问修饰符修饰

    因为它也是类的成员

三、内部类访问外部类

  1.可以访问任何属性和方法【包括私有的、静态的】

  访问方式有2种 :直接写属性名或者是外部类.this.属性【方法】

  1.1直接写属性名

    这种方式有个缺点:如果内部类定义的属性【方法】和外部类一样,会发生隐藏现象,取得的是内部类的值,若想取得外部类的值,采用外部类.this.属性【方法】

  1.2若采用直接写属性名获得外部类值,其实本质还是外部类.this.属性

  

源码:

public class Outter {
    private int a = 3;
    
     class Inner{
        public void get(){
            System.out.println(a);
        }
    }
}

反编译后的源码:Outter.class【编译成产生了2个字节码文件Outter.class和Outter$Inner.class】

public class Outter
{
    private int a;
    
    public Outter() {
        this.a = 3;
    }
    
    class Inner
    {
        public void get() {
            System.out.println(Outter.this.a);
        }
    }
}

四、外部类访问内部类

  1.访问普通属性和方法

class Outter {
    class Inner{
        int a = 3;
        
        public void get(){
            System.out.println("hello");
        }
    }
    public static void main(String[] args) {
        Outter.Inner in = new Outter().new Inner();
        System.out.println(in.a);
        in.get();
    }
}

  2.访问常量

class Outter {
    class Inner{
        static final int a = 4;
    }
    public static void main(String[] args) {
        //第一种
        Outter.Inner in = new Outter().new Inner();
        System.out.println(in.a);
        //第二种
        System.out.println(Outter.Inner.a);
    }
}

 

以上是我对成员内部类的总结,如果有不对的地方还请指出,大家共同进步!!

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM