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

你可能感兴趣的文章
SQL Server 存储过程分页。
查看>>
OSPF不能发现其他区域路由时,该怎么办?
查看>>
OSPF两个版本:OSPFv3与OSPFv2到底有啥区别?
查看>>
SQL Server 存储过程
查看>>
OSPF在大型网络中的应用:高效路由与可扩展性
查看>>
OSPF技术入门(第三十四课)
查看>>
OSPF技术连载10:OSPF 缺省路由
查看>>
OSPF技术连载11:OSPF 8种 LSA 类型,6000字总结!
查看>>
OSPF技术连载13:OSPF Hello 间隔和 Dead 间隔
查看>>
OSPF技术连载14:OSPF路由器唯一标识符——Router ID
查看>>
OSPF技术连载15:OSPF 数据包的类型、格式和邻居发现的过程
查看>>
OSPF技术连载16:DR和BDR选举机制,一篇文章搞定!
查看>>
OSPF技术连载17:优化OSPF网络性能利器——被动接口!
查看>>
OSPF技术连载18:OSPF网络类型:非广播、广播、点对多点、点对多点非广播、点对点
查看>>
OSPF技术连载19:深入解析OSPF特殊区域
查看>>
SQL Server 复制 订阅与发布
查看>>
OSPF技术连载20:OSPF 十大LSA类型,太详细了!
查看>>
OSPF技术连载21:OSPF虚链路,现代网络逻辑连接的利器!
查看>>
OSPF技术连载22:OSPF 路径选择 O > O IA > N1 > E1 > N2 > E2
查看>>
OSPF技术连载2:OSPF工作原理、建立邻接关系、路由计算
查看>>