Java成员类(内部类、匿名内部类)

Java 中内部类指的是声明在一个类内部的类,它可以访问外部类的私有变量和方法,而外部类不能直接访问内部类的成员。内部类的主要作用是为外部类提供一种封装和组织代码的方式。

内部类可以解决Java类单继承的问题,因为内部类和外部类可以相互访问。


类型: 内部类分为四种类型:

  • 成员内部类(Member Inner Class): 定义在外部类内部的非静态类。它可以访问外部类的成员。
  • 静态内部类(Static Inner Class): 定义在外部类内部的静态类。它不依赖于外部类的实例,可以直接通过外部类名访问。
  • 局部内部类(Local Inner Class): 定义在方法内部的类。它只在方法的作用域内可见。
  • 匿名内部类(Anonymous Inner Class): 没有显式类名的内部类,通常用于创建实现接口或继承类的匿名对象。

访问修饰符public仅适用于顶级类和成员类 ,不适用于本地类或匿名类。访问修饰符 protected和 private 仅适用于成员类

static 修饰的类仅适用于成员类和本地类

访问方式: 访问内部类的方式取决于内部类的型。类成员内部类通过外部类的实例访问,而静态内部类通过外部类名访问。成员类属于类的成员,所以可以调用外部类的 private 成员。外部类可以访问成员类的 private 成员


在外部类中创建成员内部类的实例:

java 复制代码
public class OuterClass {
    private int x = 10;
    // 成员类
    public class InnerClass {
        public void print() {
            System.out.println("x is " + x);
        }
    }
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.print(); // 输出:x is 10
    }
}

局部内部类的定义方式如下:

java 复制代码
class Outer {
   void print() {
      final int b = 5;
      // 局部内部类
      class Inner {
         void print() {
            System.out.println("b = " + b);
         }
      }
      Inner inner = new Inner();
      inner.print();
   }
}

匿名内部类的 定义方式如下:

匿名类不能使用修饰符,在方法的内部,对外隐藏。不能是 static ,隐式 final 类。匿
名类没有类名,没有构造方法。

java 复制代码
interface A {
   void print();
}
class Outer {
   void print() {
      // 匿名内部类
      A a = new A() {
         public void print() {
            System.out.println("匿名内部类输出");
         }
      };
      a.print();
   }
}

静态内部类的定义方式如下:

java 复制代码
class Outer {
   private static int c;
    // 静态内部类
   static class Inner {
      void print() {
         System.out.println("c = " + c);
      }
   }
}

内部类的代码演示:

java 复制代码
package com.member;

/**
 * 成员类【内部类】
 */
public class Demo {
   static int a;
   static int B = 2;
   static {
       System.out.println("demo static{}");
   }
   static class DemoInner{
       int c = 0;
       static int a;
       static int B = 4;
       static {
           System.out.println("Inner static{}");
       }
       public static void t(){
           System.out.println(123);
       }
       public void test(){
           System.out.println(Demo.B);  // 调用外部类的静态变量
           System.out.println(B);       // 调用当前内部类的静态变量
           System.out.println(this.B);  // 调用当前内部类的静态变量

           new Demo().new Demo3().test();   // 调用另一个非静态内部类的非静态方法

           Demo.test();     // 调用外部类的静态方法
       }
   }
   class Demo3{
       static int B = 6;
       static int a;
       int c =12;
       static {
           System.out.println("demo3 static{}");
       }

       public void test(){
           System.out.println(this.B);      // 调用当前非静态类的静态变量
           System.out.println(Demo.B);      //  调用外部类的静态变量
           // 在实例成员类中可以使用 外部类.this 表示外部类对象 (实例成员类是由外部类对象创建的)成员类中的 this 表示的是成员类
           System.out.println(Demo.this.B);     // 调用外部类的静态变量
       }
   }
   public static void test(){
       System.out.println(DemoInner.a);
       System.out.println(Demo3.a);
       new DemoInner().test();      // 调用静态内部类的非静态方法
   }
}
class Test{
    public static void main(String[] args) {
        Demo.DemoInner i = new Demo.DemoInner();
        System.out.println(i.c);    // 调用内部类的实例变量
        Demo.DemoInner.t();    //调用内部类的静态方法
        int a = Demo.DemoInner.a;    // 调用内部类的静态变量


        int c = new Demo().new Demo3().c;    // 调用非静态类的实例变量
        int a1 = Demo.Demo3.a;    // 调用非静态类的静态变量
        Demo.Demo3 demo3 = new Demo().new Demo3();

        Demo.test();    // 调用外部类的静态方法

    }
}

总结:内部类和外部类区别**?**

访问修饰符:
外部类只能有两种访问权限: public 以及 package - access
内部类可以有四种访问权限: public / protected / package - access / private
也就是说:访问修饰符public仅适用于顶级类和成员类,不适用于本地类或匿名类。访问修饰符 protected和 private 仅适用于成员类。
static 修饰: 外部类不可以使用 static 修饰类,内部类可以
使用:外部类可以直接被使用,内部类的使用则依赖于外部类

相关推荐
AC赳赳老秦2 小时前
司法公开数据采集应用:OpenClaw 抓取裁判文书公开信息,批量整理同类参考案例
java·大数据·python·数据挖掘·数据分析·php·openclaw
笑小枫2 小时前
用 Claude Code 推翻重写笑小枫网站
java·人工智能·spring boot·ai编程
霸道流氓气质2 小时前
ApiPost 中配置自动获取 Token 并调用业务接口完整指南
java·服务器·数据库
格林威2 小时前
工业相机Chunk功能全解析:图像嵌入时间戳、编码器元数据(附堡盟C#代码)
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
独隅3 小时前
IntelliJ IDEA 接入多种AI大模型插件终极指南(2026.1 企业合规版)
java·人工智能·intellij-idea
小大宇3 小时前
Python 集成 Conda
开发语言·python·conda
还是奇怪3 小时前
Simon Willison 用 DSPy 优化 Datasette Agent 提示词:提示工程正在变成可测试的软件工程
java·开发语言·软件工程
zfoo-framework3 小时前
1.ansible安装 2.虚拟机克隆
java
码上解惑4 小时前
从 Dify 工作流说起:常用节点怎么选、怎样组合?
java·人工智能·ai·agent·dify·智能体·spring ai
小大宇4 小时前
python flask框架 SSE流式返回、跨域、报错
开发语言·python·flask