Java内部类 #

一、内部类概述 #

内部类是定义在另一个类内部的类。

1.1 内部类分类 #

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

1.2 内部类好处 #

  • 可以访问外部类私有成员
  • 隐藏实现细节
  • 实现多重继承

二、成员内部类 #

2.1 定义 #

java
public class Outer {
    private String name = "外部类";
    
    // 成员内部类
    public class Inner {
        private String name = "内部类";
        
        public void show() {
            System.out.println(name);           // 内部类
            System.out.println(this.name);      // 内部类
            System.out.println(Outer.this.name);// 外部类
        }
    }
}

2.2 创建对象 #

java
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

2.3 访问外部类成员 #

java
public class Outer {
    private int x = 10;
    
    public class Inner {
        private int x = 20;
        
        public void display() {
            int x = 30;
            
            System.out.println(x);              // 30(局部变量)
            System.out.println(this.x);         // 20(内部类成员)
            System.out.println(Outer.this.x);   // 10(外部类成员)
        }
    }
}

三、静态内部类 #

3.1 定义 #

java
public class Outer {
    private static String staticName = "静态外部类";
    private String name = "外部类";
    
    // 静态内部类
    public static class StaticInner {
        public void show() {
            System.out.println(staticName);  // 可以访问外部类静态成员
            // System.out.println(name);     // 不能访问外部类非静态成员
        }
    }
}

3.2 创建对象 #

java
// 不需要外部类实例
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();

3.3 应用场景 #

java
public class LinkedList<E> {
    private Node<E> first;
    
    // 静态内部类:不依赖外部类实例
    private static class Node<E> {
        E item;
        Node<E> next;
        
        Node(E item, Node<E> next) {
            this.item = item;
            this.next = next;
        }
    }
}

四、局部内部类 #

4.1 定义 #

java
public class Outer {
    public void method() {
        final int localVar = 10;
        
        // 局部内部类:定义在方法内
        class LocalInner {
            public void show() {
                System.out.println(localVar);  // 可以访问局部变量
            }
        }
        
        LocalInner inner = new LocalInner();
        inner.show();
    }
}

4.2 特点 #

  • 只在定义它的方法内有效
  • 可以访问方法的局部变量(必须是final或等效final)
java
public class Outer {
    public Runnable createRunnable() {
        int count = 0;  // 等效final
        
        class MyRunnable implements Runnable {
            @Override
            public void run() {
                System.out.println(count);
            }
        }
        
        return new MyRunnable();
    }
}

五、匿名内部类 #

5.1 基本语法 #

java
new 父类/接口() {
    // 类体
};

5.2 实现接口 #

java
public interface Runnable {
    void run();
}

// 匿名内部类实现接口
Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("运行中...");
    }
};

r.run();

5.3 继承类 #

java
public abstract class Animal {
    public abstract void eat();
}

// 匿名内部类继承抽象类
Animal dog = new Animal() {
    @Override
    public void eat() {
        System.out.println("狗在吃东西");
    }
};

dog.eat();

5.4 作为方法参数 #

java
public void execute(Runnable task) {
    task.run();
}

// 匿名内部类作为参数
execute(new Runnable() {
    @Override
    public void run() {
        System.out.println("执行任务");
    }
});

// Lambda表达式简化(函数式接口)
execute(() -> System.out.println("执行任务"));

5.5 事件处理 #

java
public class Button {
    private OnClickListener listener;
    
    public void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
    }
    
    public void click() {
        if (listener != null) {
            listener.onClick();
        }
    }
    
    public interface OnClickListener {
        void onClick();
    }
}

// 使用匿名内部类
Button button = new Button();
button.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick() {
        System.out.println("按钮被点击");
    }
});

button.click();

六、内部类应用 #

6.1 Builder模式 #

java
public class Person {
    private String name;
    private int age;
    
    private Person(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
    }
    
    // 静态内部类Builder
    public static class Builder {
        private String name;
        private int age;
        
        public Builder name(String name) {
            this.name = name;
            return this;
        }
        
        public Builder age(int age) {
            this.age = age;
            return this;
        }
        
        public Person build() {
            return new Person(this);
        }
    }
}

// 使用
Person person = new Person.Builder()
    .name("张三")
    .age(25)
    .build();

6.2 迭代器实现 #

java
public class MyList<E> {
    private Object[] elements;
    private int size;
    
    public Iterator<E> iterator() {
        return new Itr();
    }
    
    // 私有内部类实现迭代器
    private class Itr implements Iterator<E> {
        int cursor = 0;
        
        @Override
        public boolean hasNext() {
            return cursor < size;
        }
        
        @Override
        @SuppressWarnings("unchecked")
        public E next() {
            return (E) elements[cursor++];
        }
    }
}

6.3 闭包 #

java
public class Counter {
    public static Runnable createCounter() {
        // 匿名内部类捕获局部变量
        int[] count = {0};  // 使用数组使其可变
        
        return new Runnable() {
            @Override
            public void run() {
                count[0]++;
                System.out.println("计数: " + count[0]);
            }
        };
    }
}

Runnable counter = Counter.createCounter();
counter.run();  // 计数: 1
counter.run();  // 计数: 2

七、总结 #

类型 定义位置 访问外部类成员 创建方式
成员内部类 类内部 可以访问所有成员 outer.new Inner()
静态内部类 类内部(静态) 只能访问静态成员 new Outer.Inner()
局部内部类 方法内部 可以访问final变量 方法内创建
匿名内部类 表达式中 可以访问final变量 new 接口/类()

内部类要点:

  • 成员内部类可以访问外部类所有成员
  • 静态内部类只能访问外部类静态成员
  • 匿名内部类常用于实现接口或继承类
  • 局部变量必须是final或等效final
最后更新:2026-03-26