think in java回顾整理之传递以及返回对象

Java是有指针的!事实上,Java中每个对象(除基本数据类型以外)的标识符都属于指针的一种。
但它们的使用受到了严格的限制和防范,不仅编译器对它们有“戒心”,运行期系统也不例外。
或者换从另一个角度说,Java有指针,但没有传统指针的麻烦。
我曾一度将这种指针叫做“句柄”,但你可以把它想像成“安全指针”(对象的实际存储位置)。

“别名”意味着多个句柄都试图指向同一个对象。

一旦准备将句柄作为一个自变量或参数传递——这是Java设想的正常方法——别名问题就会自动出现,因为创建的本地句柄可能修改“外部对象”(在方法作用域之外创建的对象)。

方法的“副作用”(Side Effect)

Java中的所有自变量或参数传递都是通过传递句柄进行的。
也就是说,当我们传递“一个对象”时,实际传递的只是指向位于方法外部的那个对象的“一个句柄”。
所以一旦要对那个句柄进行任何修改,便相当于修改外部对象。此外:
■参数传递过程中会自动产生别名问题
■不存在本地对象,只有本地句柄
■句柄有自己的作用域,而对象没有
■对象的“存在时间”在Java里不是个问题
■没有语言上的支持(如常量)可防止对象被修改(以避免别名的副作用)

本地副本:
Clone是“克隆”的意思,即制作完全一模一样的副本。

“简单复制”或者“浅层复制”:它只复制了一个对象的“表面”部分。
实际对象除包含这个“表面”以外,还包括句柄指向的所有对象,以及那些对象又指向的其他所有对象,由此类推。这便是“对象网”或“对象关系网”的由来。
若能复制下所有这张网,便叫作“全面复制”或者“深层复制”。


尽管克隆方法是在所有类最基本的Object中定义的,但克隆仍然不会在每个类里自动进行。这似乎有些不可思议,因为基础类方法在衍生类里是肯定能用的。

Java确实有点儿反其道而行之;如果想在一个类里使用克隆方法,唯一的办法就是专门添加一些代码,以便保证克隆的正常进行。

克隆时要注意的两个关键问题是:几乎肯定要调用super.clone(),以及注意将克隆设为public。
实现Cloneable接口;


Java不可能在衍生之后反而缩小方法的访问范围。换言之,一旦对象变得可以克隆,从它衍生的任何东西都是能够克隆的,除非使用特殊的机制令其“关闭”克隆能力。

Cloneable interface的实现扮演了一个标记的角色,封装到类的类型中。

两方面的原因促成了Cloneable interface的存在:
首先,可能有一个上溯造型句柄指向一个基础类型,而且不知道它是否真的能克隆那个对象。
第二个原因是考虑到我们可能不愿所有对象类型都能克隆。

通过序列化进行深层复制

安全问题上出现问题:
clone()在Object里被设置成“protected”。必须将其覆盖,并使用“implement Cloneable”,同时解决违例的问题。
只有在准备调用Object的clone()方法时,才没有必要使用Cloneable接口,因为那个方法会在运行期间得到检查,以确保我们的类实现了Cloneable。
但为了保持连贯性(而且由于Cloneable无论如何都是空的),最好还是由自己实现Cloneable。

如果希望一个类能够克隆,那么:
(1) 实现Cloneable接口
(2) 覆盖clone()
(3) 在自己的clone()中调用super.clone()
(4) 在自己的clone()中捕获违例
这一系列步骤能达到最理想的效果。


克隆的另一种替代方案:副本构建器

创建“不变对象”,令其从属于只读类。可定义一个特殊的类,使其中没有任何方法能造成对象内部状态的改变。
Integer类(以及基本的“封装器”类)用简单的形式实现了“不变性”:它们没有提供可以修改对象的方法。


从表面看,不变类的建立似乎是一个好方案。但是,一旦真的需要那种新类型的一个修改的对象,就必须辛苦地进行新对象的创建工作,同时还有可能涉及更频繁的垃圾收集。
“同志”类,并使其能够修改。
这一方法特别适合在下述场合应用:
(1) 需要不可变的对象,而且
(2) 经常需要进行大量修改,或者
(3) 创建新的不变对象代价太高
String的解决方案。

String类的对象被设计成“不可变”。
若查阅联机文档中关于String类的内容,就会发现类中能够修改String的每个方法实际都创建和返回了一个崭新的String对象,新对象里包含了修改过的信息——原来的String是原封未动的。

由于String对象是不可变的,所以能够根据情况对一个特定的String进行多次别名处理。
因为它是只读的,所以一个句柄不可能会改变一些会影响其他句柄的东西。因此,只读对象可以很好地解决别名问题。

对字串来说,这个同志类叫作StringBuffer,编译器可以自动创建一个StringBuffer,以便计算特定的表达式,特别是面向String对象应用覆盖过的运算符+和+=时。

每个String方法都小心地返回了一个新的String对象。另外要注意的一个问题是,若内容不需要改变,则方法只返回指向原来那个String的一个句柄。这样做可以节省存储空间和系统开销。

StringBuffer最常用的一个方法是append()。在计算包含了+和+=运算符的String表达式时,编译器便会用到这个方法。insert()方法采用类似的形式。这两个方法都能对缓冲区进行重要的操作,不需要另建新对象。

String类并非仅仅是Java提供的另一个类。String里含有大量特殊的类。通过编译器和特殊的覆盖或过载运算符+和+=,可将引号字符串转换成一个String。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园2.0是高校信息化建设的新阶段,它面对着外部环境变化和内生动力的双重影响。国家战略要求和信息技术的快速发展,如云计算、大数据、物联网等,为智慧校园建设提供了机遇,同时也带来了挑战。智慧校园2.0强调以服务至上的办学理念,推动了教育模式的创新,并对传统人才培养模式产生了重大影响。 智慧校园建设的解决之道是构建一个开放、共享的信息化生态系统,利用互联网思维,打造柔性灵活的基础设施和强大的基础服务能力。这种生态系统支持快速迭代的开发和持续运营交付能力,同时注重用户体验,推动服务创新和管理变革。智慧校园的核心思想是“大平台+微应用+开放生态”,通过解耦、重构和统一运维监控,实现服务复用和深度融合,促进业务的快速迭代和自我演化。 智慧校园的总体框架包括多端协同,即“端”,它强调以人为中心,全面感知和捕获行为数据。这涉及到智能感知设备、超级APP、校园融合门户等,实现一“码”或“脸”通行,提供线上线下服务端的无缝连接。此外,中台战略是智慧校园建设的关键,包括业务中台和数据中台,它们支持教育资源域、教学服务域等多个领域,实现业务的深度融合和数据的全面治理。 在技术层面,智慧校园的建设需要分期进行,逐步解耦应用,优先发展轻量级应用,并逐步覆盖更多业务场景。技术升级路径包括业务数据化、数据业务化、校园设施智联化等,利用IoT/5G等技术实现设备的泛在互联,并通过人工智能与物联网技术的结合,建设智联网。这将有助于实现线上线下一网通办,提升校园安全和学习生活体验,同时支持人才培养改革和后勤管理的精细化。 智慧校园的建设不仅仅是技术的升级,更是对教育模式和管理方式的全面革新。通过构建开放、共享的信息化生态系统,智慧校园能够更好地适应快速变化的教育需求,提供更加个性化和高效的服务,推动教育创新和人才培养的高质量发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值