博客
关于我
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/

你可能感兴趣的文章
Nodejs express 获取url参数,post参数的三种方式
查看>>
nodejs http小爬虫
查看>>
nodejs libararies
查看>>
nodejs npm常用命令
查看>>
NodeJS 导入导出模块的方法( 代码演示 )
查看>>
nodejs 的 Buffer 详解
查看>>
nodejs 读取xlsx文件内容
查看>>
nodejs 运行CMD命令
查看>>
nodejs-mime类型
查看>>
NodeJs——(11)控制权转移next
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
nodejs与javascript中的aes加密
查看>>
nodejs中Express 路由统一设置缓存的小技巧
查看>>
Nodejs中的fs模块的使用
查看>>
nodejs包管理工具对比:npm、Yarn、cnpm、npx
查看>>
NodeJs单元测试之 API性能测试
查看>>
nodejs图片转换字节保存
查看>>
nodejs字符与字节之间的转换
查看>>
NodeJs学习笔记001--npm换源
查看>>