目录

内部类

内部类的分类

 实例内部类

 静态内部类

 局部内部类


内部类

什么是内部类:

在Java中,如果一个类可以定义在另一个类的内部,那么就称为内部类。内部类的位置与外部类成员所处位置相同,因此又称作成员内部类。

内部类也是封装的一种体现。


内部类的分类

内部类分为四种:实例内部类(也叫成员内部类)、静态内部类、局部内部类、匿名内部类。

我们先用代码直观感受一下:

package Blog;

public class Test3 {
    private int a;
    int b;
    public int c;

    //1.实例内部类:
    public class InnerClass1{
        //...
    }

    //2.静态内部类:
    static class InnerClass2{
        //...
    }

    //3.局部内部类
    //先创建外部类的方法:
    public void fun(){
        class InnerClass3{
            //...
        }
    }

}

 实例内部类

成员内部类,即普通内部类,未被static修饰的内部类。

先来看一段代码1

package Blog;

class OutClass {
    private int a;
    int b;
    public int c;

    public void fun(){
        System.out.println("这是一个外部类成员方法");
    }

    // 1.实例内部类:
    public class InnerClass1{
        //内部类的成员方法
        public void innerFunc1(){
            a = 1;
            b = 2;
            c = 3;
            fun(); //内部类调用外部类的成员方法
            //内部类调用外部类的成员变量
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
        }
    }
}
public class Test{
    public static void main(String[] args) {
        //实例化一个外部对象
        OutClass out = new OutClass();
        //通过外部类的对象引用实例化一个内部类对象
        OutClass.InnerClass1 inner = out.new InnerClass1();
        //内部类对象调用内部类方法
        inner.innerFunc1();
    }
}

 其输出结果如下:

java 什么是内部类 java内部类详解_开发语言

下面我们将一一解析~ 

 通过代码1,我们提出这些疑问和总结:


  • 实例内部类所处的位置与外部类成员的位置相同,因此也受访问限定修饰符的约束

(说明:正如定义中所说,内部类它的位置与外部类中所有成员的位置相同,换言之,内部类的地位与外部类的其他成员一样,所以实例内部类写的时候可以用public、private等修饰)

  • 如何创建内部类的对象?

(首先要明白内部类对象是需要外部类对象来引用创建的,所以需要先创建外部类对象)

(以下是两种创建方式):

java 什么是内部类 java内部类详解_java_02


  • 实例内部类中可以直接访问被任何访问限定符修饰的成员(变量或者方法);

(说明:在上面的代码1中,外部类OutClass中的a,b,c以及 fun方法既有private,也有public,还有默认属性的,但我们通过内部类 InnerClass1中的成员方法 innerFunc1可以将它们全部访问到,甚至可以将变量值改变。)

  • 外部类中不能直接访问实例内部类中的成员,如果要访问必须先创建内部类的对象

(说明:比如上述代码1中,main方法里创建了一个内部类对象inner,通过内部类对象调用内部类函数innerFunc1)

  • 如果外部类与实例内部类存在相同名的成员变量会发生什么?

(说明:一般不加修饰的情况下,内部类优先访问的是其自己的)

java 什么是内部类 java内部类详解_内部类_03

  •  在此基础上,如果我们非要访问外部类中的成员变量b,该怎么做呢?

(说明:外部类名称.this.变量名)即:

java 什么是内部类 java内部类详解_java_04


(其实外部类与内部类存在相同名的变量这样的操作并无多大意义~)

以上便是实例内部类的重点知识,这里还有一点需要注意:

实例化内部类中不能定义static静态属性的成员:

        因为实例内部类的实例化过程需要外部对象的引用,但是static是类的属性,不属于某个对象,不存储在某个对象的空间中,是先加载后运行的,因此static的时机优于类的时机,即先执行static再实例化对象。


java 什么是内部类 java内部类详解_java_05

若非要在其内部定义一个静态的成员,可以在static后面加上一个“final”关键字,这样可以让变量成为常量,这样一来在程序编译时该成员已经有值了。

java 什么是内部类 java内部类详解_java 什么是内部类_06

 其次还需要注意一个细节:final一旦初始化了就不能改变了,并且一般常量名为大写;


 静态内部类

被static修饰的内部成员类。

依旧先看一段代码2

package Blog;

class OutClass2{
    public int a = 1;
    int b = 2;
    static int c = 3;
    static int d = 4;

    //静态内部类:
    static class InnerClass2{
        public void show(){
         /*   //静态内部类访问外部类中非静态成员——error
            System.out.println(a);
            System.out.println(b);*/
            //静态内部类访问外部类中静态成员
            System.out.println("c = "+c);
            System.out.println("d = "+d);
        }
    }
}
public class Test2 {
    public static void main(String[] args) {
        //创建静态类的对象
        OutClass2.InnerClass2 inner2 = new OutClass2.InnerClass2();
        inner2.show();
    }
}

输出:

java 什么是内部类 java内部类详解_开发语言_07

通过代码2,我们提出这些疑问和总结:

  •  如何创建静态内部类对象

(说明:直接通过外部类名的引用来创建,这里不需要先创建外部对象)

java 什么是内部类 java内部类详解_内部类_08

  •  一般情况下静态内部类中只能访问外部类中的静态成员

java 什么是内部类 java内部类详解_开发语言_09

 (说明:在上述代码2中,a和b均属于非静态变量,所以想要在静态内部类中直接访问是做不到的)

  • 如果非要访问外部类中的非静态成员该怎么做?

(说明:通过外部类对象来引用)

java 什么是内部类 java内部类详解_java_10



 局部内部类

定义在外部类的方法体中或{}中,该种内部类只能在其定义的位置使用。一般使用的非常少,因为它的范围较为局限。

先看代码3:

package Blog;

class OutClass3{
    public int a;
    private int b;
    int c;

    //局部内部类
    public void fun3() {
        class InnerClass3 {
            public void show() {
                a = 1;
                b = 2;
                c = 3;
                System.out.println(a);
                System.out.println(b);
                System.out.println(c);
                System.out.println("调用了一个局部内部类");
            }
        }
        InnerClass3 inner3 = new InnerClass3();
        inner3.show();
    }
}
public class Test3 {
    public static void main(String[] args) {
        OutClass3 out3 = new OutClass3();
        out3.fun3();
    }
}

输出结果:

java 什么是内部类 java内部类详解_java_11

 通过代码3,我们提出这些疑问和总结:

  • 局部内部类不能被public、static等修饰,因为其属于自身方法的;
  • 局部内部类只能在其所在方法内部使用;

(说明:在上述代码3中,若想脱离fun3方法来引用InnerClass3类是不能实现的)

java 什么是内部类 java内部类详解_jvm_12

java 什么是内部类 java内部类详解_开发语言_13