Java发布和溢出简述

news2025/2/28 15:49:27

发布和溢出

  • 前言
  • 前置知识
    • 发布
    • 溢出
      • 简述
      • 类型
  • 案例
    • 环境
    • 发布
    • 溢出
      • 溢出类型1——未完全初始化就企图获取该对象中数据
      • 溢出类型2——在构造函数中调用非private和final的方法

前言

回顾《Java并发编程实战》,这里附上一些总结和小案例加深理解。这里重点是对溢出的阐释。

前置知识

发布

发布一个对象,也就是使得其他代码块能够取得并使用该对象。最常见的发布方式就是将对象存储到公共静态域中。像Java Web中consts目录下的public static类型的变量就可以看作是对这些对象的发布。

溢出

简述

由于不当的发布,就会引起溢出。如上述将对象的存储到公共静态域中,那么任何类和线程都能看见这个域,在这个过程中就可能发生逃逸——所有该发布的对象中所能获取的数据都变成公有了。

类型

  • 对象中原本不该暴露的、私有的数据,因为该对象的发布,导致其他类或者线程能够通过该对象获取到其中的私有数据,那么这些私有数据就等于是间接的溢出了。
  • 类的构造函数在构造对象时,尚未完全构造,就已经隐式地将自身(this)引用暴露出去了,导致了运行过程中出现了未知错误。这里有两种形式,具体看下面代码。

案例

环境

Maven3.X、JDK17

发布

这里展示最简单的一个发布案例,现在的URL就是所有的类和线程都能进行URL的使用了。

public class UrlConsts {
    public static final String URL = "www.baidu.com";
}

溢出

溢出类型1——未完全初始化就企图获取该对象中数据

这里ThisEscape 构造过程中,隐含的就把this引用给了CustomizeListener ,如果线程执行过程中,val在doSomething 前尚未初始化,打印出来的val结果就是0。

public class EscapeTest {
    @Test
    public void test() {
        new MethodEscapeTest ("qyl");
    }
}

class ThisEscape {
    private int val;

    public ThisEscape() {
        // 构造还未完成就已经发布了this引用,导致val还未初始化就被CustomizeListener调用了打印val的方法。
        new CustomizeListener ( ) {
            @Override
            public void run() {
                doSomething ( );
            }
        }.run ( );
        val = 10;
    }

    // 溢出1,val大概率是0,属于未完成初始化就this引用溢出了
    public void doSomething() {
        System.out.println (val);
    }
}

class CustomizeListener implements Runnable {

    @Override
    public void run() {}
}

执行结果如下:
在这里插入图片描述
解决方案:延迟线程的启动,通过工厂模式来解决。

public class EscapeTest {
    @Test
    public void test2(){
        CustomizeListener listener = ThisEscape2.newInstance ( );
        listener.run ();
    }
}


class ThisEscape2{
    private int val;
    private final CustomizeListener listener;
    private ThisEscape2() {
        listener = new CustomizeListener (){
            @Override
            public void run() {
                System.out.println (val);
            }
        };
        this.val = 10;
    }

    public static CustomizeListener newInstance(){
        ThisEscape2 escape2 = new ThisEscape2 ( );
        return escape2.listener;
    }
}

class CustomizeListener implements Runnable {

    @Override
    public void run() {
        System.out.println ("hello");
    }
}

运行结果如下:
在这里插入图片描述

溢出类型2——在构造函数中调用非private和final的方法

在初始化子类的时候,隐含着先对父类无参构造函数的调用,而父类的构造函数又调用了methodEscape ,该方法被子类重写了,所以会去执行子类重写后的方法,那么很明显name是未进行初始化的,所以导致name这里出现了问题,始终是null,通过private和final可以解决这个问题的出现。

public class EscapeTest {
    @Test
    public void test() {
        new MethodEscapeTest ("qyl");
    }
}

class ThisEscape {
    public ThisEscape() {
        System.out.println ("invoke father's constructor");

        // 构造函数中调用非 final 和 private的方法,导致溢出
        methodEscape ( );
        // private 来解决上述问题
        methodEscapeSolution1();
        // final 解决上述问题
        methodEscapeSolution2();
    }

    // 溢出2. 方法可能被重写,那么可能this引用溢出,导致后面的方法调用有问题
    public void methodEscape() {
        System.out.println ("call father's method");
    }

    // 正常功能 通过private解决构造函数中调用方法出现this引用溢出
    private void methodEscapeSolution1(){
        System.out.println ("call father's method1");
    }
    // 正常功能 通过 final 解决构造函数中调用方法出现this引用溢出
    public final void methodEscapeSolution2(){
        System.out.println ("call father's method2");
    }
}
class MethodEscapeTest extends ThisEscape {
    private final String name;

    public MethodEscapeTest(String name) {
        this.name = name;
        System.out.println ("invoke son's constructor");
    }

    @Override
    public void methodEscape() {
        System.out.println ("son's name ----> " + name);
    }

}

该代码块执行结果如下:
在这里插入图片描述
由于修正后的method1、method2子类无法重写所以不会产生问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

差分约束

前置知识: 最短路问题、SPFA判环,为了保证学习效果,请保证已经掌握前置知识之后,再来学习本章节! 引出 当我们遇到一个不等式组,比如下面这个 \begin{cases} x_{1}-x_{3} \leq 5 \\ x_{1}-x_{2} \leq 2 \\ x_{2}-x_{…

3.2 图像分类

文章目录LeNet(小图像)LeNet在手写数字识别上的应用LeNet在眼疾识别数据集iChallenge-PM上的应用数据集准备查看数据集图片定义数据读取器启动训练AlexNet(大图像)VGG(深度)GoogLeNet(深度兼广度…

苹果电脑怎么用移动硬盘ntfs?快速读取和编辑Mac外置移动硬盘

苹果电脑怎么用移动硬盘ntfs?如果你对电脑比较熟悉的话,可能知道NTFS磁盘格式。该格式专门为Windows系统设计的,也称为Windows NT文件系统。从Windows系统迁移到Mac可能是一项相当困难的任务,因为NTFS格式的硬盘在Mac上不能正常工…

音视频面试涨知识(一)

1 直播中为什么会出现花屏、黑屏、闪屏? 主播没有打开摄像头权限,推流端没有做好权限校验处理。 采集Camera数据,就要开始编码,如果编码失败,没有推送数据,那就会黑屏。 拉流段遇到不支持的视频格式&…

某讯滑块验证码反汇编分析-第二章

某讯滑块验证码反汇编分析-第二章反汇编难点分析反汇编帮助跟踪参数生成函数反汇编难点分析 首先就是上一章提到的,指令的顺序是会变的 假设某序号为1的指令为【I[I.length - 2] I[I.length - 2] I.pop();】 这个指令可能在下一次请求的时候,序号变…

C++ Reference: Standard C++ Library reference: Containers: map: map: end

C官网参考链接&#xff1a;https://cplusplus.com/reference/map/map/end/ 公有成员函数 <map> std::map::end C98 iterator end(); const_iterator end() const; C11 iterator end() noexcept; const_iterator end() const noexcept;返回指向结束的iterator 返回一个指…

常用代码模板2——基础算法

构思算法&#xff1a;可以先想暴力解法&#xff0c;然后观察时间复杂度&#xff0c;如果超时&#xff0c;再考虑优化&#xff0c;优化的方向就是时间复杂度要下降&#xff0c;下表可以给出一些算法选择的参考&#xff1a; 暴力枚举 -> 枚举优化 -> 正解 数据范围时间复…

Qt扫盲-QTabWidget理论总结

QTabWidget理论总结1. 简述2. 用法流程3. 选项卡设置3. 页面信息3. 外观4. 扩展1. 简述 QTabWidget 提供一个选项卡栏和一个“页面区域”&#xff0c;用于显示与每个选项卡相关的页面。默认情况下&#xff0c;选项卡栏显示在页面区域上方&#xff0c;但可以使用不同的配置&…

智能合约简单介绍

本学期学习了区块链的课程&#xff0c;作业是对于智能合约学习后的报告&#xff1a; 1 智能合约简单了解 1.1智能合约是什么 智能合约是由事件驱动的、具有状态的、部署于可共享的分布式数据库上的计算机程序&#xff0c;多用IF-THEN语句。狭义来说&#xff0c;智能合约是设计…

函数式编程 | 图文详解 | 系统性学习 | 无知的我费曼笔记

无知的我正在复盘函数式编程 该笔记特点是 重新整理了涉及资料的一些语言描述、排版而使用了自己的描述对一些地方做了补充说明。比如解释专有名词、类比说明、对比说明、注意事项提升了总结归纳性。尽可能在每个知识点上都使用一句话 || 关键词概括更注重在实际上怎么应用提出…

70. 利用 ALV 实现增删改查系列之二:仅让 ALV 报表某一列允许被编辑

本系列前一篇文章 69. 利用 ALV 实现增删改查系列之一:让 ALV 报表进入可编辑状态,我们介绍了如何让 SAP ABAP ALV 报表进入可编辑状态。在该状态下,ALV 报表的每一行,每一列都可以被任意修改,如下图所示: 但是在实际的项目中,更常见的需求是,ALV 报表只允许部分列能够…

【Vue脚手架】总结笔记

脚手架文件结构 ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── assets: 存放静态资源 │ │ └── logo.png │ │── component: 存放组件 │ │ └── HelloWorld.vue │ │…

Springboot 整合 ireporter 实践

背景 这段时间&#xff0c;在做项目时&#xff0c;设计到需要带参数的批量生成报告。尝试了很多方法&#xff0c;包括grafana等BI工具。虽然grafana这种BI工具可以在线查看&#xff0c;但是无法导出。甚至当想把报告整合邮件发送时&#xff0c;grafana就显得无能为力了。于是在…

Sql Server 占用内存高,不释放内存问题处理记录(腾讯电脑管家小火箭清内存)

问题&#xff1a; 本人仓库管理系统厂家&#xff0c;项目上反应生产线箱码不能上传到我们系统&#xff0c;我们的WMS软件退出后重新登录也一直登录失败&#xff0c;并且服务器上数据库占用内存过高&#xff0c;SSMS数据库连接不上。 好家伙SQL Server占用了34个G内存。 接口…

前端基础(十二)_overflow属性、clear属性、vertical-align属性

overflow属性 overflow的第一个属性值是x轴方向的属性&#xff0c;第二个值是y周方向的属性 <style>.box1 {width: 150px;height: 50px;等价于下面两个属性/* overflow: hidden auto; */overflow-x: hidden;overflow-y: auto;}</style>1、overflow-x 只包含水平方…

VS2019编译QT6源码

现在QT在线安装只有QT6.2以上的版本和QT5.15&#xff0c;其他版本就需要自己编译&#xff0c;本文讲解在vs2019环境下编译qt6.1.3源码。 1 编译准备 从清华大学镜像站&#xff0c;下载源码&#xff0c;地址如下&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/qt/archive/…

【C++】继承/多态/文件

文章目录一、继承1 继承中的对象模型2 继承中构造和析构顺序3 继承中同名属性和函数处理方式&#xff08;隐藏&#xff09;4 继承同名静态成员属性和函数处理方式5 多继承语法6 菱形继承&#xff08;虚继承&#xff09;二、多态1 多态的原理剖析&#xff08;虚函数表指针&#…

【OpenSourceC#】JEngine框架

前言 一个完全依赖ILRuntime的框架&#xff0c;集成好了ILRuntime和AB资源热更&#xff0c;想用ILRuntime的可以很方便使用。 对着作者的文档JEngine看看框架功能都是怎么实现的。 看下文档中提到的功能如下 JEngine框架核心 热更资源工具 AssetMgr&#xff0c;框架集成…

询盘回复流程及外贸11步流程

询盘回复流程&#xff1a; 从事外贸的新手经常在网上寻找各种各样的外贸干货知识。其实&#xff0c;你不仅要关注某个环节的小细节&#xff0c;还要有“宏观”的思维。分过程、分步骤地梳理外贸工作&#xff0c;是外贸工作中十分重要的一个环节。今天&#xff0c;按照一般的回…

点云中点法向量,点拟合的直线,点拟合的平面

点云中点法向量 计算步骤&#xff1a; 找到点pi相邻点集合S所有点Vi,然后去中心化,并构造协方差矩阵,公式如下: 二维点云该点曲率计算方法&#xff1a; 三维点云该点曲率计算方法&#xff1a; 最小特征值对应的特征向量就是点的法向量 Eigen::Vector2d ComputeNormal(std::v…