Java学习笔记-day03-类名.this:内部类引用外部类实例

类名.this是啥意思?

今天在看尚硅谷的课程时里面讲了这么一句话:
集合在遍历时需要先创建一个容器,存放集合的数据,这样做浪费内存
想去验证下,就翻了翻ArrayList的迭代过程源码

ArrayList的迭代器类ItrArrayList的内部类)源码中有这么一段代码

Object[] elementData = ArrayList.this.elementData;

在这里插入图片描述

结论:

  1. 这行代码是Java中内部类(Inner Class)中的一种用法,通过类名.this来引用外部类的实例。

    在上述代码中,ArrayList.this表示在ArrayList的非静态内部类Itr中,引用外部的ArrayList实例的elementData属性。

  2. 在Java中,内部类有时候会引用外部类的实例。为了明确地表示使用的是外部类的实例而不是内部类的实例,可以使用外部类名.this的形式。

为什么内部类可以拿到外部类的实例?

结论

  • 成员内部类能够访问外部类的实例是因为编译器会在内部类中隐式地维护一个对外部类实例的引用。

解释

在 Java 中,内部类(Inner Class)可以访问其外部类(Enclosing Class)的实例,这是因为内部类被认为是外部类的一部分。这种访问的机制涉及到内部类的实现方式以及编译器的处理。

有两种主要的内部类:成员内部类(Member Inner Class)和静态内部类(Static Inner Class)。

  1. 成员内部类: 成员内部类是一个非静态的内部类,它隐含地持有对外部类实例的引用。当创建成员内部类的实例时,实际上会与外部类的实例关联起来。这就允许成员内部类访问外部类的实例变量和方法,同时也能够访问外部类的私有成员。

    public class OuterClass {
        private int outerVar;
    
        public class InnerClass {
            public void doSomething() {
                // 在内部类中可以访问外部类的实例变量
                outerVar = 10;
            }
        }
    }
    
  2. 静态内部类: 静态内部类是一个与外部类实例无关的内部类。它不隐含地持有对外部类实例的引用,因此在静态内部类中不能直接访问外部类的非静态成员。如果需要访问外部类的实例,必须通过外部类的对象来实现。

    public class OuterClass {
        private static int staticVar;
    
        public static class StaticInnerClass {
            public void doSomething() {
                // 在静态内部类中不能直接访问外部类的实例变量
                // 但可以访问外部类的静态变量
                staticVar = 20;
            }
        }
    }
    

总体而言,内部类能够访问外部类的实例是因为编译器会在内部类中隐式地维护一个对外部类实例的引用。这样的设计允许内部类更容易地与其外部类进行交互。

成员内部类中一定能获取到外部类实例吗?

结论

能,创建成员内部类实例需要通过外部类实例来创建

解释

在Java中,当创建内部类的实例时,通常是要先创建外部类的实例,然后通过这个外部类实例来创建内部类实例。因此,在访问外部类实例的情况下,通常可以假定外部类实例已经存在。

例如,对于成员内部类而言,它隐含地持有对外部类实例的引用,因此在创建成员内部类实例之前,通常需要有外部类的实例存在。

public class OuterClass {
    private int outerVar;

    public class InnerClass {
        public void doSomething() {
            // 在内部类中可以访问外部类的实例变量
            outerVar = 10;
        }
    }

    public static void main(String[] args) {
        OuterClass outerInstance = new OuterClass();
        OuterClass.InnerClass innerInstance = outerInstance.new InnerClass();
        innerInstance.doSomething();
    }
}

对于静态内部类,由于它不隐含地持有对外部类实例的引用,因此在创建静态内部类实例时,不需要先创建外部类的实例。静态内部类的创建方式如下:

public class OuterClass {
    private static int staticVar;

    public static class StaticInnerClass {
        public void doSomething() {
            // 在静态内部类中不能直接访问外部类的实例变量
            // 但可以访问外部类的静态变量
            staticVar = 20;
        }
    }

    public static void main(String[] args) {
        OuterClass.StaticInnerClass innerInstance = new OuterClass.StaticInnerClass();
        innerInstance.doSomething();
    }
}

总体而言,在使用内部类的情况下,通常会有外部类实例存在或者通过外部类实例来创建内部类实例。

成员内部类中修改外部类的实例的值,可以吗?

结论

可以(静态内部类中是不能的)

解释

在成员内部类中是可以修改外部类的实例的成员变量的。这是因为成员内部类会隐含地持有对外部类实例的引用。以下是一个示例:

public class OuterClass {
    private int outerVar;

    public class InnerClass {
        public void modifyOuterVar(int newValue) {
            // 在内部类中修改外部类的实例变量
            outerVar = newValue;
        }
    }

    public static void main(String[] args) {
        OuterClass outerInstance = new OuterClass();
        OuterClass.InnerClass innerInstance = outerInstance.new InnerClass();

        System.out.println("Before modification: " + outerInstance.outerVar);
        
        // 调用内部类的方法来修改外部类的实例变量
        innerInstance.modifyOuterVar(42);

        System.out.println("After modification: " + outerInstance.outerVar);
    }
}

在上述例子中,InnerClass 中的 modifyOuterVar 方法可以修改外部类 OuterClassouterVar 变量。

请注意,在静态内部类中是不能直接修改外部类的实例变量的,因为静态内部类没有隐含地持有对外部类实例的引用。如果需要在静态内部类中修改外部类的实例变量,需要通过外部类的实例来进行。

回到最初的问题,显然,集合在遍历时需要先创建一个容器是不正确的
ArrayList在迭代时直接通过成员内部类就可以直接访问到外部类实例数据ArrayList.this.elementData,通过它加上游标即可直接获取集合数据,实现遍历操作
猜想:
Fail-Fast机制的集合迭代的时候是不会创建新容器的。也是直接取原集合中的数据。
Fail-Safe机制的并发集合迭代的时候,可能也不需要创建新容器。
比较多的说法是并发集合会创建一个新的集合副本,再迭代,这样才能实现Fail-Safe,但是我看ConcurrentHashMap的keys()方法,并没有。也可能是代码太长了没找到,或者版本比较新有改动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/304413.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 PyCharm 中使用 Copilot

GitHub Copilot 由 OpenAI Codex 提供支持,可帮助用户在编辑器中实时工作。 它使用强大的 GPT-3 模型版本,该模型在大量开源代码上进行训练。 此外,GitHub Copilot 可在不同的 IDE(集成开发环境)上使用,包…

局域网IP地址冲突、环路的罪魁祸首是什么?

中午好,我的网工朋友。 这个时代,网络已经贯穿了人们的生活,对企业而言,办公信息化更是离不开网络支持。 为了提高安全管理和信息化水平,很多企业都建立了完善的办公信息系统,但一些企业在网络建设方面还…

【嵌入式】git工具基础命令学习笔记 | 嵌入式Linux

文章目录 前言一、git基础指令二、git分支管理2.1、一些基础命令2.2、时间回溯2.3、新建分支,删除分支,重命名分支 前言 参考:飞凌嵌入式ElfBoard ELF-1 软件学习手册 chatGPT 一、git基础指令 首先我们新建一个名叫git的文件夹&#xff0…

GreatSQL喊你来考证啦~

GreatSQL社区全网开放且全免费的GCA和GCP双等级考核认证,赶快来参与吧~ 认证课程介绍 GreatSQL社区开放GCA与GCP双等级认证课程,课程全面覆盖GreatSQL的安装、使用、优化、安全高可用等方面,包含构建主从和MGR架构,优化提升性能…

【动态代理详解】

文章目录 1. 关于代理1.1 代理的概述1.1.1 什么是动态代理1.1.2 动态代理能做什么 1.2 什么是代理1.2.1 生活中的代理1.2.2 为什么要找中介? 1.3 开发中的代理模式(代理)1.3.1 使用代理模式的作用 1.4 实现代理的方式 2. 静态代理2.1 什么是静…

百川智能发布角色大模型 ,零代码复刻角色轻松满足游戏领域定制需求

2024年1月9日,百川智能发布角色大模型Baichuan-NPC,深度优化了“角色知识”和“对话能力”,使模型能够更好的理解上下文对话语义,更加符合人物性格地进行对话和行动,让角色栩栩如生。此外,对于游戏领域AI角…

各版本 操作系统 对 .NET Framework 与 .NET Core 支持

有两种类型的受支持版本:长期支持 (LTS) 版本和标准期限支持 (STS) 版本。 所有版本的质量都是一样的。 唯一的区别是支持的时间长短。 LTS 版本可获得为期三年的免费支持和补丁。 STS 版本可获得 18 个月的免费支持和修补程序。 有关详细信息,请参阅 .N…

找不到文件Computer Management.lnk怎么办

win10系统右键“此电脑”,在右键菜单选择“管理”弹出错误提示: windows找不到文件Computer Management.lnk 打开电脑C盘路径C:\Windows\System32,找到compmgmt.msc文件 给compmgmt.msc文件创建一个快捷键选择文件compmgmt.msc,右…

联盛德-安全物联网芯片w800

联盛德-安全物联网芯片w800 前言一、w800简介?芯片外观 总结 前言 本文介绍w800的基本信息,详细规格,后续有时间会介绍如何适配openharmony的过程。 一、w800简介? W800 芯片是一款安全 IoT Wi-Fi/蓝牙 双模 SoC 芯片。支持 2.…

软件测试|Linux三剑客之sed命令详解

简介 sed(Stream Editor)是一款流式文本编辑器,在 Linux 和类 Unix 系统中广泛使用。它的设计目的是用于对文本进行处理和转换,可以用于替换、删除、插入、打印等操作。sed 命令通过逐行处理文本,允许您使用简单的命令…

物联网协议Coap中Californium CoapClient解析

目录 前言 一、CoapClient对象 1、类定义 2、Client方法调用 二、发送请求 1、构建请求 2、发起请求 3、接收响应 总结 前言 在之前的博客中物联网协议Coap之Californium CoapServer解析,文中简单介绍了CoapServer的实现。在物联网开发环境中,除了…

git安装教程 Windows 附安装包链接

Git是一款分布式源代码管理工具(版本控制工具) 。 git的作用 当你需要做一个大工程的时候,文件的管理无疑是非常庞大的工作,因为你需要不断的修改更新文件内容,同时可能还要保留旧版本保证可以复原,这样就需要备份多个版本的文件…

【镜像压缩】linux 上 SD/TF 卡镜像文件压缩到实际大小的简单方法(树莓派、nvidia jetson)

文章目录 1. 备份 SD/TF 卡为镜像文件2. 压缩镜像文件2.1. 多分区镜像文件的压缩(树莓派、普通 linux 系统等)2.2. 单分区镜像文件的压缩(Nvidia Jetson Nano 等) 3. 还原镜像文件到 SD/TF 卡4. 镜像还原后处理4.1. 镜像分区调整4…

【MySQL】:用户管理

用户管理 一.用户1.用户信息2.创建用户3.修改密码4.删除用户 二.数据库权限1.给用户授权2.回收权限 如果在以下操作中出现以下报错 可以使用刷新权限 一.用户 1.用户信息 MySQL中的用户,都存储在系统数据库mysql的user表中。 字段解释: host&#xff…

基于SSM+Vue的学校社团管理系统(Java毕业设计)

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

基于代理IP的多线程爬虫实现

目录 前言 1. 爬虫的基本原理 2. 多线程爬虫的优势 3. 代理IP的应用 4. 基于代理IP的多线程爬虫实现 步骤1:导入必要的模块 步骤2:定义爬虫函数 步骤3:创建线程并启动爬虫 总结 前言 本文将介绍如何使用Python编写一个基于代理IP的多…

UR机器人旋转矢量和俯仰角的转换

我们在使用机器人的时候,总是习惯使用俯仰角来描述机器人末端姿态的变换。这样更直观,但是机器人为了插值方便计算,总是采用旋转矢量来来描述机器人的姿态。该旋转矢量及不直观,单一轴角度旋转时还可以理解,当两个轴或…

少儿编程 2023年12月中国电子学会图形化编程等级考试Scratch编程四级真题解析(判断题)

2023年12月scratch编程等级考试四级真题 判断题 11、创建自制积木时,参数只能添加数字和文本 答案:错 考点分析:考查自制积木的使用,创建自制积木的时候参数可以是数字、文本以及布尔值类型;所以答案错误 12、分查找是我们经常用的查找方式,它比顺序查找效率更高,比如…

前端中什么是DOM对象

DOM(文档对象模型)是一种编程接口,用于HTML和XML文档。它提供了一种将文档结构表示为树结构的方式,这使得程序和脚本能够动态地访问和更新文档的内容、结构和样式。 在前端开发中,DOM是非常重要的概念。当浏览器加载网…

高级别智能驾驶业务系列:港口作业仿真系统

在港口无人水平运输场景中,经纬恒润提供了车、路、网、云、图全栈式自研解决方案,包含了自动驾驶车辆、路侧车路协同、全场高可靠定位、5G远程驾驶、运营调度管理、数字孪生、仿真系统、 高精地图等专业模块,组成了一套完整的智慧港口解决方案…