java-basics [nested classes]

本文详细介绍了Java中的嵌套类概念,包括静态嵌套类和内部类的区别与使用场景。探讨了嵌套类如何提高代码的封装性和组织性,并解释了局部类和匿名类的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌套类nested classes
定义在类内部的类,叫做嵌套类。

class OuterClass {
    ...
    class NestedClass {
        ...
    }
}

根据类是否为静态的,嵌套类可以分为静态嵌套类和内部类。
(嵌套类、静态嵌套类、内部类)。
嵌套类是外部类的成员,内部类(非静态嵌套类)可以访问外部类的成员,即使是那些私有成员。静态嵌套类不能访问外部类的成员。嵌套类可以是private public protected甚至是package private(modifiers)。外部类只能是public。

使用嵌套类原因

  • 只在一个地方使用的一种逻辑地组织方法。如果一个类只对另一个类有用,把它嵌套到另一个类中是符合逻辑的,并且这样的“帮助类”使得整个package结构更合理。
  • 增加封装性。类A和B,如果B需要访问A的成员,但是A的成员需要对外不可见(即private类型),那么B可以作为A的内部类,进而访问那些成员,而且,B也可以对外隐藏起来。
  • 可读性和便于维护。嵌套类和它们的外部类位置更近。

静态嵌套类

就像类的方法和变量,静态嵌套类和它的外部类是关联的。并且像静态方法一样,静态嵌套类不能直接访问外部类的实例变量或方法,只能通过对象引用。静态嵌套类与它的外部类(和其他类)的实例成员交互,就像其他顶级类一样;效果上,就像是顶级类在另一个顶级类中一样:
访问静态嵌套类:
OuterClass.StaticNestedClass
创建静态嵌套类的对象,语法:
OuterClass.StaticNestedClass nestedClass = new OuterClass.StaticNestedClass();

内部类

像实例方法和变量,内部类与其外部类的实例相关联,并且可以直接访问那个对象的方法和域。因为内部类和实例关联,它不能定义静态成员。

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

内部类的实例成员,存在于外部类的实例中。一个InnerClass的实例,只能在OuterClass的实例中存在并且可以直接访问外部实例的成员。
初始化一个内部类,必须定义和初始化外部类。在外部类对象内创建内部类对象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
有两种特殊类型内部类:局部类(local classes)和匿名类(anonymous classes)。

局部类 (local classes)

在方法中声明的内部类。

匿名类 (anonymous classes)

方法中声明的没有名字的内部类。就像没有名字的局部类。在只需要只用局部类一次的时候,使用匿名类。

声明匿名类

局部类是类的声明,而内部类是表达式。局部类和内部类:

public class HelloWorldAnonymousClasses {
    interface HelloWorld {
        public void greet();
    }
    public void sayHello() {
        class EnglishGreeting implements HelloWorld {
            public void greet() {
            }
        }
        HelloWorld englishGreeting = new EnglishGreeting(); // local class
        HelloWolrd frenchGreeting = new HelloWorld() { // anonymous class
            String name = "tout le monde";
            public void greet() {
                System.out.println(name);
            }
        };
        englishGreeting.greet();
        frenchGreeting.greet();
    }
    public static void main(String ... args) {
        HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }
}
匿名类语法

匿名类表达式就像调用一个constructor,只不过代码快中含有对类的定义。
匿名类表达式包含:

  • new
  • 要实现的接口或要继承的类
  • 一对括号,含有constructor的参数,就像初始化类的对象。因为接口没有constructor,所以接口的括号内总是空的。
  • 类的声明体。其中,可以有函数声明但不能有语句。
    因为匿名类的定义是表达式,因此它必须是表达式的一部分。上面例子中,初始化frenchGreeting对象的表达式中有匿名类定义的表达式。
外部作用域的局部变量,声明和访问匿名类的成员
  • 匿名类可以访问其enclosing class的成员。
  • 匿名类不能访问作用域内的非final或者等效final类型的局部变量。
  • 与嵌套类有相同的shadowing
    限制:
  • 匿名类中不能有静态初始化或者成员接口
  • 匿名类不能有constructor
  • 可以有静态成员即常量
  • 可以有域、额外的方法(接口或父类之外的方法)、实例初始化、局部类

修饰符(Modifiers)

就像其他类成员一样,public private protected 和package private

Shadowing

同名声明遮蔽问题,无法仅仅用名字访问一个被遮蔽的声明。

public class ShadowTest {
    public int x = 0;
    class FirstLevel { // package private inner class.
        public int x = 1;
        void methodInFirstLevel(int x) {
            System.out.println("x = " + x); // 23
            System.out.println("this.x = " + this.x); // 1
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); // 0
        }
    }
    public static void main(String ... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

定义了三个变量x,ShadowTest成员变量,内部类FirstLevel成员变量,函数methodInFirstLevel的参数。methodInFirstLevel函数的参数x遮蔽了FirstLevel的成员变量,因此用this指明作用域(enclosing scope)。
通过类名,引用更大范围作用域的成员变量。ShadowTest.this.x,从methodInFirstLevel函数访问ShadowTest的成员变量x

序列化

非常不鼓励序列化内部类,包括匿名内部类和局部类。当编译器编译某些构建时,例如内部类,它创建一个synthetic constructs:类、方法、域和其他构建,在源码中没有相应构建。它使得编译器实现新的java语言特性,而不用改变jvm。然而不同编译器实现起来可能不同,以为着.class文件可能不同。因此如果序列化和反序列化的JRE实现不同,会有兼容问题。


资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值