Java对象及其引用

认知复杂度——估算项目代码的理解成本 1. 摘要 Cognitive Complexity:认知复杂度,是由sonarQube设计的一个算法,算法将一段程序代码被理解的复杂程度,估算成一个整数——可以等同于代码的理解成本。 IntellliJ IDEA支持sonar插件,可以实时计算函数的认知复杂度,当复杂度过高时将提醒重构。 认知复杂度的计算基于以下三规则:语法糖不增加理解难度、打断线性代码执行增加理解难度、多层嵌套增加理解难度。 2. 历史背景(可略过) 2.1 概要 最初工业界普遍使用圈复杂度(Cyclomatic Complexity) 阅读详情
 
       初学Java时,在很长一段时间里,总觉得基本概念很模糊。后来才知道,在许多Java书中,把对象和对象的引用混为一谈。可是,如果我分不清对象与对象引用,那实在没法很好地理解下面的面向对象技术。把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路。
       为便于说明,我们先定义一个简单的类:
       class Vehicle {
int passengers;      
int fuelcap;
int mpg;
}
有了这个模板,就可以用它来创建对象:
       Vehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。
2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。
3)左边的“Vehicle veh1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。
我们可以把这条语句拆成两部分:
Vehicle veh1;
veh1 = new Vehicle();
效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。
       在堆空间里创建的实体,与在数据段以及栈空间里创建的实体不同。尽管它们也是确确实实存在的实体,但是,我们看不见,也摸不着。不仅如此,我们仔细研究一下第二句,找找刚创建的对象叫什么名字?有人说,它叫“Vehicle”。不对,“Vehicle”是类(对象的创建模板)的名字。一个Vehicle类可以据此创建出无数个对象,这些对象不可能全叫“Vehicle”。
       对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。
       为了形象地说明对象、引用及它们之间的关系,可以做一个或许不很妥当的比喻。对象好比是一只很大的气球,大到我们抓不住它。引用变量是一根绳,可以用来系汽球。
       如果只执行了第一条语句,还没执行第二条,此时创建的引用变量veh1还没指向任何一个对象,它的值是null。引用变量可以指向某个对象,或者为null。它是一根绳,一根还没有系上任何一个汽球的绳。执行了第二句后,一只新汽球做出来了,并被系在veh1这根绳上。我们抓住这根绳,就等于抓住了那只汽球。
       再来一句:
       Vehicle veh2;
就又做了一根绳,还没系上汽球。如果再加一句:
       veh2 = veh1;
系上了。这里,发生了复制行为。但是,要说明的是,对象本身并没有被复制,被复制的只是对象引用。结果是,veh2也指向了veh1所指向的对象。两根绳系的是同一只汽球。
       如果用下句再创建一个对象:
veh2 = new Vehicle();
则引用变量veh2改指向第二个对象。
       从以上叙述再推演下去,我们可以获得以下结论:(1)一个对象引用可以指向0个或1个对象(一根绳子可以不系汽球,也可以系一个汽球);(2)一个对象可以有N个引用指向它(可以有N条绳子系住一个汽球)。
       如果再来下面语句:
       veh1 = veh2;
按上面的推断,veh1也指向了第二个对象。这个没问题。问题是第一个对象呢?没有一条绳子系住它,它飞了。多数书里说,它被Java的垃圾回收机制回收了。这不确切。正确地说,它已成为垃圾回收机制的处理对象。至于什么时候真正被回收,那要看垃圾回收机制的心情了。
       由此看来,下面的语句应该不合法吧?至少是没用的吧?
new Vehicle();
不对。它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象,就不需要用引用变量来系住它。最常见的就是打印字符串:
       System.out.println(“I am Java!”);
字符串对象“I am Java!”在打印后即被丢弃。有人把这种对象称之为临时对象。
       对象与引用的关系将持续到对象回收。但是,关于这一点,打算在下文“简述Java回收机制”再说。
 
数据结构中顺序表的结构和时间复杂度计算 文章系统介绍了数据结构中的顺序表及相关算法分析。主要内容包括:1)数据结构基本概念,区分线性与非线性逻辑结构;2)算法分析的核心指标(时间复杂度和空间复杂度)及其计算方法;3)线性表的定义与顺序表实现,包括管理结构体设计、初始化、增删节点等操作。重点阐述了顺序表通过连续内存存储来维护元素间线性关系的特点,并提供了完整的C语言实现示例。文章强调算法效率的时空权衡,展示了不同时间复杂度随问题规模增长的显著差异。 阅读详情

相关推荐

环路复杂度:量化代码逻辑复杂度的核心指标与测试用例设计实践

环路复杂度是衡量程序控制流复杂度的核心软件度量指标,它源于图论,通过计算程序线性独立路径的数量来量化其逻辑复杂度。其核心原理在于将代码抽象为控制流图,并基于边、节点和连通分量数量进行计算。该指标的技术价值在于为测试用例设计提供了客观、量化的科学依据,帮助测试工程师精准评估测试覆盖的基准,有效提升测试设计的系统性和说服力。在软件工程实践中,环路复杂度常与测试用例设计、代码质量门禁和持续集成流程紧密结合,广泛应用于单元测试、代码审查和重构优先级评估等场景。通过自动化工具计算环路复杂度,可以高效识别高复杂度代码区

dianchamian8747的博客 367

Java创建对象的5种方式

可以随意的调用构造器。

weixin_41979002的博客 968

时间复杂度计算与分析方法详解:从O(1)到O(n!)的实战指南

时间复杂度是算法分析的核心概念,用于评估代码执行时间随输入规模增长的趋势。其原理基于大O表示法,通过忽略常数项和低阶项,聚焦最高阶项来描述算法的渐进效率。掌握时间复杂度的计算,能帮助开发者在系统设计时预判性能瓶颈,优化代码效率,尤其在高并发、大数据处理等场景下至关重要。本文以Python代码为例,详细解析了顺序执行、循环嵌套、递归调用等典型结构的分析方法,并对比了从常数阶O(1)到阶乘阶O(n!)的常见复杂度及其适用场景,为工程实践中的算法选型与性能优化提供清晰指引。

weixin_33585822的博客 223

js vm报错_js vm报错

我们都知道JVM的内存管理是自动化的,Java语言的程序指针也不需要开发人员手工释放,JVM的GC会自动的进行回收,但是,如果编程不当,JVM仍然会发生内存泄露,导致Java程序产生了OutOfMemoryError(OOM)错误。产生OutOfMemoryError错误的原因包括:java.lang.OutOfMemoryError: Java heap spacejava.lang.OutOf...

weixin_32239523的博客 892

程序员/学生党看过来:用Obsidian + Markdown搞定高效笔记、代码片段与项目规划

本文详细介绍了如何利用Obsidian和Markdown构建高效的技术知识库,特别适合程序员和学生党。通过工程化目录架构设计、必备插件组合、可执行代码块实践以及知识图谱构建技术,帮助用户提升40%以上的知识检索效率。文章还提供了版本控制集成和项目全周期管理系统等实用技巧,是Obsidian基础使用手册的终极指南。

weixin_30275415的博客 441

数学建模实战:从问题分析到Python代码实现的完整方法论

数学建模是运用数学工具解决实际问题的核心方法,其本质在于将复杂现实抽象为可计算的数学模型。建模过程遵循从问题定义、变量识别、假设简化到算法选型的逻辑链条,关键在于理解数据特征与问题结构。在工程实践中,Python凭借Pandas、NumPy、SciPy等库成为主流工具,能高效实现数据处理、预测分析(如时间序列ARIMA、机器学习LightGBM)与优化求解(如线性规划PuLP)。本文以华为杯数学建模竞赛E题为案例,复盘从多源时序数据预处理、模型构建到代码工程化落地的全流程,重点探讨如何避免常见陷阱,并实现模

weixin_34416649的博客 300

JAVA包装临时对象

<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> 包装临时对象 当一个方法需要返回两个及以上字段时,我们一般会封装成一个临时对象返回,现在有了Pair和Triple就不需..

kaige8312的博客 819

矩阵求逆算法的时间与空间复杂度对比:从理论到实践

本文深入对比了矩阵求逆算法的时间与空间复杂度,从理论到实践剖析了伴随矩阵法、高斯消元法和LU分解法等主流方法。伴随矩阵法因阶乘级复杂度而缺乏实用性,高斯消元法及其变种提供了稳定的O(n³)时间复杂度解决方案,而LU分解法则在需要重复求解时更具优势。文章还探讨了针对对称正定矩阵的Cholesky分解等优化策略,并强调了在实际应用中优先使用线性方程组求解器而非显式求逆的重要性。

kafka6courier的博客 715

java springboot 在测试类中声明临时Bean对象

先 SpringBootTest 声明这是个测试类 然后 Import 导入我们刚刚写的 configBean。这里 我们用Configuration声明 我们这是个配置类 然后 里面配置一个Bean。因为 我们String本身是个字符串对象 所以 它也可以被设置为Bean。这样配置 是不会运行到其他地方的 仅作用于我们当前测试类 非常的好用。这样 我们声明了一个bean 字符串类型 叫 msg。中 我们讲了怎么在测试类中设置临时属性。然后 我们测试类代码编写如下。然后 我们条件装配msg。

weixin_45966674的博客 391

数据结构基础:线性表的实现与应用全解析

线性表作为数据结构中最基础的概念之一,其核心特征在于元素的有序性和有限性。从原理上看,线性表通过顺序存储(数组)或链式存储(指针)两种方式实现,分别对应着不同的时间复杂度特性。在工程实践中,顺序表凭借其O(1)随机访问特性,常被用于需要高频查询的场景;而链表则因其动态内存分配优势,更适合频繁插入删除的操作。缓存友好性和负载因子等性能指标,成为选择实现方式的关键考量。典型应用场景包括Excel数据匹配、多项式运算等,而混合结构如Redis的quicklist则展现了两种实现方式的优势结合。掌握线性表对于理解栈

weixin_26938645的博客 314

C++时间复杂度实战:从算法原理到工程优化与性能陷阱

时间复杂度是衡量算法执行效率的核心概念,它使用大O符号描述算法运行时间随数据规模增长的趋势。其原理在于分析基本操作的执行次数,忽略常数和低阶项,关注增长级别。掌握时间复杂度的技术价值在于,它能让开发者在编码前预判性能瓶颈,在系统设计时做出合理的数据结构和算法选择,是编写高性能、可扩展代码的基石。在应用场景上,无论是优化线上服务的热点函数、进行Code Review,还是应对技术面试,时间复杂度分析都至关重要。本文以C++为例,结合**哈希表**和**std::vector**等容器操作,深入剖析了常见时间复

weixin_32932149的博客 348

java临时对象持久对象_Java对象持久性:联盟状态

java临时对象持久对象 在这个虚拟小组中,InfoQ.com(Floyd Marinescu)和ODBMS.org(Roberto V. Zicari)的编辑询问了一组领先的持久性解决方案架构师,以他们对Java社区中持久性联盟的当前状态的看法。 小组成员: Mike Keith :JPA 1.0联合规范负责人,架构师,Oracle TopLink和Java持久性技术 Ted N...

cunfu6353的博客 973

计算机数据结构考研知识点汇总,数据结构考研知识点总结.pdf

数据结构考研真题及知识点解析考察目标1. 掌握数据结构的基本概念、基本原理和基本方法。2. 掌握数据的逻辑结构、存储结构及基本操作的实现,能够对算法进行基本的时间复杂度与空间复杂度的分析。3. 能够运用数据结构的基本原理和方法进行问题的分析与求解;具备采用C、C++或Java语言设计与实现算法的能力。第2章 线性表一、考研知识点(一)线性表的定义和基本操作(二)线性表的实现1.顺序存储2.链式存储...

weixin_33561350的博客 2716

Big O复杂度实战指南:从代码到性能的可预测性

Big O表示法是算法时间与空间开销的增长趋势描述,其核心在于建模‘基本操作’在输入规模扩大时的执行次数变化。它基于RAM计算模型,屏蔽硬件与语言差异,聚焦逻辑结构本身。理解O(1)、O(log N)、O(N)、O(N²)等常见复杂度,不仅能预判系统在用户量从千级到百万级时的性能衰减曲线,更能指导工程决策——例如用哈希表替代线性搜索实现从O(N²)到O(N)的质变,或识别list.index()、list.pop(0)等Python中隐藏的O(N)陷阱。本文结合7类真实代码模式与线上故障案例,揭示复杂度如何

weixin_34378767的博客 368

线性数据结构:原理、应用与性能优化实战

线性数据结构是计算机科学中最基础的数据组织方式,包括数组、链表、栈和队列等基本形态。其核心原理是通过元素间的线性关系实现数据存储与操作,具有明确的时间复杂度特征。在工程实践中,合理选择线性结构能显著提升程序性能,如在电商系统中使用链式结构存储热门搜索关键词可降低40%更新时间。典型应用场景涵盖数据库索引(B+树)、消息队列、函数调用栈等关键领域。通过内存布局优化(如数据导向设计)、特殊结构实现(环形缓冲区)以及算法改进(快慢指针法)等手段,可以进一步释放线性结构的潜力。理解不同线性结构的特性及其在缓存友好性

weixin_34221112的博客 322

扫雷游戏背后的秘密:用FloodFill算法实现自动展开(附BFS/DFS代码对比)

本文深入解析了经典扫雷游戏中自动展开功能背后的FloodFill算法原理。通过对比广度优先搜索(BFS)与深度优先搜索(DFS)两种实现策略,详细阐述了其核心思想、代码实现及性能差异,并提供了可直接运行的C++代码示例,帮助开发者深入理解算法在游戏交互中的实际应用。

weixin_29248313的博客 470

SNOW 2.0流密码遭扩展域快速相关攻击,密钥恢复复杂度降至2^80

流密码是现代密码学中实现高速加密的核心技术,其原理是通过伪随机密钥流与明文进行异或运算。其技术价值在于为实时通信提供高效保密,广泛应用于移动通信、无线网络和磁盘加密等场景。然而,流密码的安全性高度依赖于密钥流的随机性,相关攻击正是通过分析密钥流内部的统计偏差来威胁其安全。本文聚焦于针对经典流密码SNOW 2.0的最新分析进展,探讨了在扩展域GF(2^32)上构建线性近似的方法,并详细阐述了如何利用快速相关攻击技术,将密钥恢复的数据与时间复杂度大幅降低,动摇了该算法的安全假设。

weixin_34208283的博客 442

线性与差分密码分析:从统计偏差到差异传播的密钥恢复实战

在密码学领域,分组密码(如AES、DES)是构建安全通信的核心组件,其安全性依赖于算法的混淆与扩散特性。线性密码分析和差分密码分析是两种经典的密码分析方法,它们分别从统计偏差和差异传播的角度,揭示算法中可能存在的弱点。线性分析通过寻找明文、密文与密钥比特间微小的线性近似关系,利用海量数据进行统计分析,逐步恢复密钥信息,适用于已知明文攻击场景。差分分析则专注于追踪特定输入差分在加密过程中的传播规律,通过选择明文对构建高概率差分路径,高效恢复轮密钥,多见于选择明文攻击。这两种方法不仅是评估算法安全性的重要工具,

cuililai5127的博客 394
上一篇: 三种内存分配模式
下一篇: Java的垃圾回收(Garbage Collection)机制
beepbug
博客等级 码龄22年 39粉丝 15原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值