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

你可能感兴趣的文章
Node出错导致运行崩溃的解决方案
查看>>
node安装及配置之windows版
查看>>
Node提示:error code Z_BUF_ERROR,error error -5,error zlib:unexpected end of file
查看>>
Node读取并输出txt文件内容
查看>>
NOIp2005 过河
查看>>
NOIp模拟赛二十九
查看>>
NOPI读取Excel
查看>>
NoSQL&MongoDB
查看>>
NoSQL介绍
查看>>
NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty()
查看>>
Now trying to drop the old temporary tablespace, the session hangs.
查看>>
npm error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。要解决此问题,1) 安装
查看>>
npm install digital envelope routines::unsupported解决方法
查看>>
npm install 卡着不动的解决方法
查看>>
npm install 报错 ERR_SOCKET_TIMEOUT 的解决方法
查看>>
npm install报错,证书验证失败unable to get local issuer certificate
查看>>
npm install无法生成node_modules的解决方法
查看>>
npm node pm2相关问题
查看>>
npm run build 失败Compiler server unexpectedly exited with code: null and signal: SIGBUS
查看>>
npm run build报Cannot find module错误的解决方法
查看>>