博客
关于我
Java 内部类及其原理
阅读量:424 次
发布时间:2019-03-06

本文共 2734 字,大约阅读时间需要 9 分钟。

Java内部类详解:成员、局部、匿名与静态内部类的区别与实现

在Java编程中,内部类是开发者常用的一个概念。它允许在一个类的内部定义另一个类,这个内类可以与外类的成员变量和方法进行交互。以下将从多个角度详细阐述Java内部类的实现机制和使用场景。

1. 成员内部类

成员内部类是定义在外部类的成员位置(如方法、字段)中的内部类。要注意的是,当成员内部类与外部类拥有相同名称的成员变量或方法时,默认情况下会访问内部类的成员。要访问外部类的同名成员,需要使用外部类.this修饰。

创建成员内部类的方式

创建成员内部类的方式如下:

public class Main {    private String name;        public class Inner {        public void sayHello() {            System.out.println("Hello, " + name);        }    }        public static void main(String[] args) {        Main main = new Main();        Main.Inner inner = main.new Inner();        inner.sayHello();    }}

成员内部类的访问权限

成员内部类可以具有private、protected、public或默认访问权限。private修饰的成员内部类只能在外部类的内部访问。

2. 局部内部类

局部内部类是定义在方法或作用域中的类。它的访问权限仅限于其定义的方法或作用域内。局部内部类可以与外部类的成员进行交互,并且可以返回值或引用。

局部内部类的使用场景

局部内部类通常用于处理某一特定方法中的逻辑。例如:

public class Main {    public class LocalInner {        public void doSomething() {            System.out.println("Local Inner is running");        }    }        public void method() {        class LocalInnerImpl implements LocalInner {            @Override            public void doSomething() {                System.out.println("Local Inner Implementation");            }        }        LocalInnerImpl localInner = new LocalInnerImpl();        localInner.doSomething();    }}

3. 匿名内部类

匿名内部类是我们在日常开发中使用最频繁的内部类类型。它通常用于实现接口或继承其他类。匿名内部类的优点是编译时会自动为其生成名称(如Main$1),不需要手动指定。

匿名内部类的典型用途

匿名内部类常用于创建线程或观察者:

public class Main {    public Runnable createAnonymousRunnable() {        return new Runnable() {            @Override            public void run() {                System.out.println("Anonymous Runnable is running");            }        };    }        public static void main(String[] args) {        Runnable runnable = createAnonymousRunnable();        runnable.run();    }}

匿名内部类的特点

匿名内部类没有构造器,无法直接创建实例,只能通过实现接口或继承其他类。它的生命周期与引用对象保持一致。

4. 静态内部类

静态内部类与成员内部类不同,它们不依赖于外部类的实例。静态内部类可以像静态成员变量一样独立存在。

创建静态内部类的方式

创建静态内部类的方式如下:

public class Main {    public static class StaticInner {        public void sayHello() {            System.out.println("Hello, Static Inner");        }    }        public static void main(String[] args) {        StaticInner inner = StaticInner.class.newInstance();        inner.sayHello();    }}

内部类实现原理

内部类能够访问外部类成员的原因在于其内部包含外部类的引用。通过反编译内部类文件可以观察到这一点。例如,以下是反编译后的Main$Inner.class文件内容:

public class Main$1 extends Main {    public final java.lang.String name;        public Main$1(Main m, java.lang.String name) {        this.m = m;        this.name = name;    }        public void sayHello() {        System.out.println("Hello, " + name);    }}

可以看到,内部类实际上持有外部类的引用,并在构造函数中将该引用传递进来。

匿名内部类的特殊性

匿名内部类之所以可以不使用final修饰外部类成员字段,是因为它持有外部类实例的引用。所有对外部类成员字段的修改都会直接反映到外部类实例中,从而避免了数据不一致问题。

通过以上分析,可以清晰地了解Java内部类的实现原理及其应用场景。理解这些概念对于Java编程具有重要意义。

转载地址:http://eshuz.baihongyu.com/

你可能感兴趣的文章
OneBlog Shiro 反序列化漏洞复现
查看>>
oneM2M
查看>>
Oneplus5重装攻略
查看>>
one_day_one--mkdir
查看>>
ONI文件生成与读取
查看>>
Vue 项目中实现高效的消息提示与确认对话框功能(模版)
查看>>
Online PDF to PNG、JPEG、WEBP、 TXT - toolfk
查看>>
onlstm时间复杂度_CRF和LSTM 模型在序列标注上的优劣?
查看>>
onlyoffice新版5.1.2版解决中文汉字输入重复等问题
查看>>
onnx导出动态输入
查看>>
onnx导出动态输入
查看>>
onScrollStateChanged无效
查看>>
onTouchEvent构造器
查看>>
on_member_join 和删除不起作用.如何让它发挥作用?
查看>>
oobbs开发手记
查看>>
OOM怎么办,教你生成dump文件以及查看(IT枫斗者)
查看>>
OOP
查看>>
OOP之单例模式
查看>>
OOP向AOP思想的延伸
查看>>
Vue element 动态添加表单验证
查看>>