成员&局部&匿名&静态内部类...内部类的作用你真的明白吗?

Java内部类是定义在另一个类里面的类。使用内部类的主要原因是它能够访问其外部类的成员,包括私有成员。内部类是一种强大的封装工具,因为它能够将一部分类的实现隐藏在另一个类的内部。Java中的内部类主要可以分为四种类型:

1. 成员内部类(Non-static Nested Class)

  • 定义在类的内部,和方法、变量同级。
  • 可以无条件访问外部类的所有成员属性和方法(包括私有的)。
  • 需要先创建外部类的实例,然后通过外部类的实例创建内部类的实例。

使用Java内部类是一种编程技巧,允许你将一个类定义在另一个类的内部,从而密切地连接两个类的关系,同时保持它们的代码逻辑上的整洁。内部类提供了几个重要的特性和优势,可以在特定的编程场景中非常有用。

为什么需要使用内部类呢?

内部类主要有以下几个用途和优点:

  • 对同一个包中其他类隐藏:内部类可以被声明为私有(private)、保护(protected)或者公共(public),或者默认不指定(包级私有),这样可以控制其他类对内部类的访问级别,实现封装和隐藏。
  • 访问外部类的成员:内部类方法可以访问定义这个类的外围(外部)类中的数据,包括私有的字段和方法。这种能力使内部类成为实现某些特定功能的理想选择,尤其是当这些功能需要访问外围类的私有数据时。

使用内部类访问对象状态

  • 访问数据字段:内部类不仅可以访问自身的数据字段,还可以直接访问创建它的外围类对象的数据字段。
  • 隐式引用:每个内部类的实例都自动持有一个指向其外围类实例的隐式引用。这个引用在内部类的代码中是不可见的,但它允许内部类访问外围类的成员。
  • 外围类的引用设置:当内部类的对象被创建时,外围类的引用隐式地传递给内部类。编译器会自动修改内部类的构造器,添加一个外围类引用的参数。
  • 私有内部类:将内部类声明为私有,限制了只有外围类可以构造和访问内部类的对象,这提供了一种强大的封装机制。

内部类的特殊语法规则

  • 外围类引用语法:在内部类中,可以通过 OuterClass.this 表达式访问外围类的实例。这种语法在访问外围类的成员时特别有用,尤其是在内部类和外围类有同名成员的情况下。
  • 创建内部类对象的语法:要从外围类的非静态上下文之外创建内部类的实例,需要使用特殊的语法 outerObject.new InnerClass(constructionParameters)。这种语法明确指出了内部类实例的创建依赖于外围类的一个实例。

内部类是Java中一个强大的特性,允许更紧密地将两个类的行为和状态绑定在一起,同时还提供了优秀的封装性。通过内部类,可以实现更加模块化和维护性更好的代码设计。

2. 局部内部类(Local Classes)

  •  定义在一个方法或任意作用域内。
  • 只在定义它的方法或作用域内可见和可用。
  • 可以访问外部类的成员和final或effectively final的局部变量。

局部内部类是定义在外围类的某个方法中的类,仅在该方法的作用域内可见和可用。

  • 作用域限定:声明局部类时,不能有访问说明符(即publicprivate)。局部类的作用域被限定在声明这个局部类的块中。
  • 对外部世界的隐蔽性:局部类对外部世界完全不可见,甚至外围类中非定义该内部类的其他方法和代码都不能访问它。

由外部方法访问变量

​​​​​​​

  • 局部类不仅能访问外部类的字段,还能访问局部变量,但这些局部变量必须是实际上的最终变量(即effectively final),这意味着一旦赋值就不能更改。
  • 编译器会检测对局部变量的访问,在局部内部类中为每个变量建立相应的实例字段,并将局部变量复制到构造器中,从而能够初始化这些实例字段。

3. 匿名内部类(Anonymous Inner Classes)

  •  没有名称的局部内部类。
  • 用于实例化接口或抽象类,常用于事件监听器或小型委托任务。
  • 可以立即定义和实例化。

4. 静态内部类(Static Nested Classes) 

  • 定义为外部类的静态成员,可以像其他静态成员一样访问。
  • 可以访问外部类的所有静态成员和方法,包括私有的。
  • 不需要外部类的实例即可创建。
  • 如果某个内部类不需要外围类的引用,可以将内部类声明为static
  • 只有内部类可以声明为static
  • 与常规内部类不同, 静态内部类可以有静态字段和方法
  • 在接口中声明的内部类自动是public和static

5. 创建和使用内部类的例子

  • 成员内部类
public class OuterClass {
    class InnerClass {
        // ...
    }
}
// 使用
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();

  • 局部内部类

public class OuterClass {
    public void myMethod() {
        class LocalInnerClass {
            // ...
        }
        LocalInnerClass lic = new LocalInnerClass();
    }
}

  • 匿名内部类

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("匿名内部类示例");
    }
}).start();

  • 静态内部类

public class OuterClass {
    static class StaticNestedClass {
        // ...
    }
}
// 使用
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

内部类提供了一种强大的机制来组织和封装复杂的系统,它们使代码逻辑更加紧密且易于维护。

6. 总结

​​​​​​​

Java 内部类是定义在另一个类内部的类,它们使得可以将一些逻辑更紧密地封装于类的内部,而不是暴露在外部。Java内部类主要分为四种:成员内部类、局部内部类、匿名内部类和静态内部类。

  1.  成员内部类:它是最常见的内部类形式,定义在类内部,类似于类的一个成员。成员内部类可以无条件访问外部类的所有成员属性和方法,即使是私有的。这种内部类对外部世界是隐藏的,但可以被外部类的方法或者与之相同的包中的其他类访问。 
  2.  局部内部类:局部内部类是定义在一个块里面的类,比如一个方法或者一个作用域块。它们仅在定义它们的块内部可见和可用。局部内部类对实现细节的隐藏尤其有用。 
  3.  匿名内部类:匿名内部类是没有名字的内部类。它通常用于实现接口或继承类的简短实例。由于没有类名,所以不能使用构造器创建实例,而是通过实例化表达式来构造。匿名内部类是一种轻量级的编码方式,特别适合创建简单的实现或继承类的实例。 
  4.  静态内部类:静态内部类是用static修饰的内部类,它不需要外部类的实例就可以被创建。静态内部类不能访问外部类的实例成员,只能访问外部类的静态成员。这种内部类通常用于当内部类与外部类的实例无关时。 

每种类型的内部类都有其特定的用途和优点,例如提高封装性、更好地组织代码、减少类的命名冲突等。

  • 24
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值