Java相对于c而言,是一门比较安全的语言,免去了指针操作带来的各种不安全因素,但是当你构建一个类,给别人提供接口,在交互的过程也会带来不少麻烦,有时候甚至会改变对象内部的不可变状态,请看下面例子。...,有女友的程序员朋友都知道,初次约会的时候,女生最喜欢男友准时准点地在那里等,而不是干巴巴地让女孩子在等,等久了,是要删游戏装备的,哈哈。...所以约会的时间不能随意改变,在这里用了final关键字修饰(注意,final修饰变量,如果是基本类型,则值当然不可变,若是对象,指的是它不能指向其他对象,而引用的对象本身是可变的)。...那这是否意味着date不可变了呢,答案是否定的,请看: Calendar cal = Calendar.getInstance(); cal.set(2016, 3, 22);...,还是有不少出差错的可能的,软件是一件需要不断精细打磨的艺术品,所有的程序员都是工匠,是艺术家。
Python中所有类型的值都是对象,这些对象分为可变对象与不可变对象两种: 不可变类型 float、int、str、tuple、bool、frozenset、bytes tuple自身不可变,但可能包含可变元素...,a+=b和a=a+b等价,对于可变对象并不等价,dict和set不支持+=和+操作符。...,可通过拷贝来避免不同对象间的相互影响。...,只是若原对象中存在可变属性/字段,则浅拷贝产生的对象的属性/字段引用原对象的属性/字段,深拷贝产生的对象和原对象则完全独立: l1 = [1, 2, 3] l2 = l1.copy() print(l1...可变类型切片 l1 = [1, 2, 3] l2 = l1[:] print(l1 is l2) # False 可变类型的copy方法 [].copy() {}.copy
什么是不可变的对象呢?...我们从下图可以看到当定义String str = "test1"时,Java实际上做了这个操作(我们在这里不讨论String关于使用new和不使用new,以及堆内存分配的问题)。 ?..."test"变量其实并没有改变,改变的只是str的引用,将str的引用重新指向在常量池中新创建的"test1"变量,这即是"不可变的对象"。 那么何为"不可变的对象引用"呢?...不可变的对象引用”。...21 22 } 23 24 } 以上便是“不可变对象”与“不可变的对象引用”的区别,为什么要区分这两个概念,这是为后面Java多线程的线程安全先做下铺垫。
数据类型分为可变、不可变。可变对象表示可以原处修改该数据对象,不可变对象表示必须创建新对象来保存修改后的数据。...在基础数据类型中: 数值、字符串、元组、frozenset是不可变对象 列表、set、dict是可变对象 对于可变对象,比如有一个列表L,查看它的id以及第一个元素的id。...>>> L[0]="aa" >>> L ['aa', 'b', 'c'] >>> id(L) 23099392 发现列表的id并没有改变,也就是列表的内存地址仍然是那一块。这表示列表是可变序列。...但是,如果查看第一个元素的id,会发现已经改变了: >>> id(L[0]) 61863232 这说明,虽然列表的内存地址没有改变,但是列表中的第一个元素的地址已经改变了。...正如上面修改字符串"a"为"aa"的结果。 假如列表L中的第一个元素仍然是一个嵌套在L中的列表,因为列表是可变对象,现在修改L的第一个元素,这第一个元素的地址不会改变。
什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变。...当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。 可变对象,该对象所指向的内存中的值可以被改变。...如果是可变对象add = aee,它们指向同一地址(id相同)是肯定的。但不是同一对象的不同引用,因为如果是的话,aee的改变会引起add的改变,再tuple中并不是这样。...所以tuple是不可变对象,但又和str和数值类型稍微有点区别。平常说的tuple不可变更多时候是指里面存放的值不能被改变(有些特殊情况,如tuple里面存放了list,可改变list里的元素。...可变对象由于所指对象可以被修改,所以无需复制一份之后再改变,直接原地改变,所以不会开辟新的内存,改变前后id不变。
String str = "test"; str = "test1"; 我们从下图可以看到,当定义String str = "test1"时,其实不是真正改变了str的内容,而是改变了str的引用。...那么何为"不可变的对象引用"呢?...final只保证引用类型变量所引用的地址不会改变,即一直引用同一个对象,但是这个对象的内容(对象的非final成员变量的值可以改变)完全可以发生改变(比如final int[] intArray;,intArray...为什么String对象是不可变的? 要理解String的不可变性,首先看一下String类中都有哪些成员变量。...,当然最关键的是每次计算时都得到相同的结果,所以也保证了对象的不可变。
如何在 Java 中创建不可变对象?我以前以为所有对象都是不可变的,因为如果你改变一个 String 实例的内容,它总是会创建一个新的 String 对象并指向该对象。...Java 中的可变类和不可变类是什么? 在 Java 中,可变类和不可变类的概念指的是对象创建后其状态是否可以更改。可变类是指实例创建后可以修改的类,而不可变类一旦创建就不能改变其状态。...可变对象的状态可以通过修改其字段或属性的方法来改变。例如,StringBuilder 和 ArrayList 都是可变类。...Java 中不可变对象与可变对象的区别 以下是 Java 中可变类和不可变类之间的一些主要区别: 1. 修改 可变对象在创建后可以修改,但不可变对象在创建后不能修改。 2....状态更改 可变对象允许更改状态,但不可变对象的状态在创建时是固定的。 4. 使用案例 当你需要经常修改对象,或想表示状态会随时间变化的实体时,可变对象就派上用场了。
python是一种解释型的语言,执行效率要比C这样的编译型语言差得多,但是也应该注意它的效率。...python的各种数据类型,按更新模型可以分为可变类型(如列表、字典)和不可变类型(如数字、字符串和元组)。多使用可变类型,它的执行效率比不可变类型要高。...在《37-生成密码/验证码》中,将结果保存到了一个名为 result 的变量中。...result 是字符串,字符串不可变,所以python在工作时,首先要申请一段内存储 result 的初值(空串''),随机取得一个字符后(如'a'),result += 'a'实际上是要重新申请一个新的内存...如果变量 result 使用列表,只需要为其分配一次内存即可,因为列表是可变的。
众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢?可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。...从打印结果可以看出,s的值确实改变了。那么怎么还说String对象是不可变的呢?其实这里存在一个误区:s只是一个String对象的引用,并不是对象本身。...“不可变”对象的。...但是一般我们不这么做。这个反射的实例还可以说明一个问题:如果一个对象,他组合的其他对象的状态是可以改变的,那么这个对象很可能不是不可变对象。...例如一个Car对象,它组合了一个Wheel对象,虽然这个Wheel对象声明成了private final 的,但是这个Wheel对象内部的状态可以改变, 那么就不能很好的保证Car对象不可变。
,那么我们首先抛出今天的议题,为什么不建议HashMap的key使用可变对象呢?...更进一步说,为什么有些公司或团队强制使用HashMap的key使用String,Long等等不可变对象呢?...在详细介绍答案之前,再问一个问题,在代码使用层面,如果key是可变对象,对我们的get查询操作有影响吗?有什么影响? 首先,还是先看一下get方法的代码: ?...那假如说key是可变对象,比如说key是一个人,value是他的工作信息,第一次put之后,插入到Entry 数组具体位置,那如果这个key对应的人对象内部属性发生变化,体重变动,那么会导致key...Map实例的时候,根据业务场景尽可能避免使用可变对象作为key,最常用的就是 Map或者Map。
看了一下代码,发现修改数据的代码是这样的 // popupData是修改的数据,修改完后,赋值给对应的表格数据 this.tableData[this.currentRow] = this.popupData...注意事项(以下内容摘自官方文档) 由于 JavaScript 的限制,Vue 不能检测以下数组的变动: 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue...当你修改数组的长度时,例如:vm.items.length = newLength 举个例子: var vm = new Vue({ data: { items: ['a', 'b',...'c'] } }) vm.items[1] = 'x' // 不是响应性的 vm.items.length = 2 // 不是响应性的 为了解决第一类问题,以下两种方式都可以实现和 vm.items...$set 实例方法,该方法是全局方法 Vue.set 的一个别名: vm.
要用JSON解码复杂对象,请使用object_hook参数检查JSON字符串是否包含复杂对象。...return complex(objct['real'], objct['img']) return objct # 使用带有object_hook的json加载方法用于检查是否复杂的对象...它包含三种不同的编码方法,分别是 default(o) –在子类中实现,并为o对象返回序列化对象。...encode(o) –与json.dumps()方法相同,返回Python数据结构的JSON字符串。 iterencode(o) –一对一表示字符串并编码对象o。...借助JSONEncoder类的encode()方法,我们还可以对任何Python对象进行编码。
今天小明哥要分享的主题是:改变类定义的神器-metaclass 看到标题,你可能会想改变类的定义有什么用呢?什么时候才需要使用metaclass呢?...Python类的上帝-type 说到metaclass,我们首先必须清楚一个最基础的概念就是对象是类的实例,而类是type的实例,重复一遍: 对象是类的实例 类是type的实例 在面向对象的编程模型中,...你可能感受不到这有多强大,要知道想在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。...虽然metaclass的编写会比较复杂,但ORM的使用者用起来却异常简单。...metaclass 是 Python 黑魔法级别的语言特性,它可以改变类创建时的行为,这种强大的功能使用起来务必小心。 看完本文,你觉得装饰器和 metaclass 有什么区别呢?
软件系统是物理世界的映射。在一个没有出现任何变化的物理世界中,是没有必要开发一个软件系统来提高效率的。那么值对象的“不可变”具体是指什么不可变呢?值对象不可变,为什么实体就可变了呢?...不可变,是指软件系统中能够唯一确定一个主体的属性不可变。从这个维度来看实体和值对象都不可变。 不可变,不是说软件系统中这些关键属性一旦持久化,就不能修改了。是可以修改的。...走两步: 场景一:操作日志 软件系统中的操作日志的格式一般是“什么时间什么人进行了什么操作”。 什么人,在软件系统中如何表示呢?操作人ID。不可变,是指操作人ID相同。...只要这四个属性相同,就代表了物理世界上相同的位置。 值对象的领域模型与数据模型示例 不可变,是指一个人员的省、市、县、街道四个属性任何一个改变了,就变成一个新地址了。...即这个人员在软件系统中的地址就映射到了物理世界中另一个位置了。这个人员的老地址在软件系统中找不到了。不可变,指代表的业务含义不可变。
---- 二、不可变对象 2.1 什么是不可变对象 其实不光是String对象,Java中的很多对象都符合上述不可改变状态的特性。...不可变对象所提供的方法,不会改变自身的状态,最多构造一个新状态的新对象的返回,这也与上述思路完全契合。...比如颜色数值和颜色名可以因为多线程的调动而对应不上。 3.2定义不可变对象的策略 以下的一些规则是创建不可变对象的简单策略。...并非所有不可变类都完全遵守这些规则,不过这不是编写这些类的程序员们粗心大意造成的,很可能的是他们有充分的理由确保这些对象在创建后不会被修改。但这需要非常复杂细致的分析,并不适用于初学者。...2)不共享可变对象的引用。当一个引用被当做参数传递给构造函数,而这个引用指向的是一个外部的可变对象时,一定不要保存这个引用。如果必须要保存,那么创建可变对象的拷贝,然后保存拷贝对象的引用。
接着上一篇文章说,上一篇创建的对象没有向外部提供直接设置属性值的入口。都是在new 创建对象时,给定默认值。 本文在创建新的实例时指定属性值。...name 和 dept 属性则不是 amy 对象本地的,而是从 amy 对象的 __proto__属性获得的。...修改所有后代的某属性值 如果想在运行时修改一个对象的属性值并且希望该值被所有该对象的后代所继承,您就不能在该对象的构造器函数中定义该属性。而应该将该属性添加到该对象所关联的原型中。...因而,修改Foo.prototype 的属性,将改变所有通过 new Foo() 创建的对象的属性的查找。...因此,通过“原型继承(prototype inheritance)”,对象与其他对象之间形成关系。通过比较对象的 __proto__ 属性和函数的prototype 属性可以检测对象的继承关系。
看到了有给 Python 函数参数的默认值传递可变对象,以此来加快斐波那契函数的递归速度,代码如下: def fib(n, cache={0: 0, 1: 1}): if n not in cache...n - 2) return cache[n] 是不是很新奇,居然可以这样,速度真的非常快,运行结果如下: 不过,我劝你不要这样做,而且 IDE 也会提示你这样做很不好: 这是因为,万物皆对象...,Python 函数也是对象,参数的默认值就是对象的属性,在编译阶段参数的默认值就已经绑定到该函数,如果是可变对象,Python 函数参数的默认值在会被存储,并被所有的调用者共享,也就是说,一个函数的参数默认值如果是一个可变对象...id 是一样的,说明它们用到的是 li 是同一个,这就参数的默认值是可变对象的逻辑,对于所有的调用者来讲,是共享的。...最好的方式是不要使用可变对象作为函数默认值。
PropertyUtilsBean 在实际的工程设计中,当我们设计了一个复杂的数据对象,对象中还嵌套有子对象,子对象可能还会有更多的嵌套时,如果没有工具辅助,要获取一个对象的子成员下的子成员,需要写好几行代码逐级获取...往涉及到这种复杂的多级嵌套的子成员变量读写,程序代码都会变得很臃肿,繁琐。...为了实现对复杂数据对象子成员的读写,需要支持嵌套的多级字段名表达式定义的字段名。...然后使用相同的方法查询为此属性返回的对象,以获取名为 的属性的属性获取器name2,依此类推。最终检索或修改的属性值是由最后一个名字节点元素标识的值。...写操作支持自动尝试创建成员对象,即当要访问的嵌套字段名 name1.name2.name3中任何一个中间节点为null时会尝试创建一个空的节点以最大限度能让节点遍历进行下去。
https://github.com/itwanger/toBeBetterJavaer 01、什么是不可变类 一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable...其中,synchronized(同步)关键字是最简单最入门的一种解决方案。 假如说类是不可变的,那么对象的状态就也是不可变的。...这样的话,每次修改对象的状态,就会产生一个新的对象供不同的线程使用,我们程序员就不必再担心并发问题了。 02、常见的不可变类 提到不可变类,几乎所有的程序员第一个想到的,就是 String 类。...虽然调用 substring() 方法对 cmower 进行了截取,但 cmower 的值没有改变。...为了解决这个问题,我们需要为不可变类的定义规则追加一条内容: 如果一个不可变类中包含了可变类的对象,那么就需要确保返回的是可变对象的副本。
参数的默认值: 使用可变对象使用不可变对象 默认参数使用可变对象会怎样? 先复原需求 定义一个函数,为传入的列表(list)尾部添加一个“end”元素。 ...(列表是一个可变的对象 —— 这是重点) 再看执行过程: 1. ...3. print(addend(lst)) 当调用函数并传入实参(lst)的时候,并不是把lst列表中的内容拷贝到lt列表中,而是使lt指向的对象发生了改变,使lt也指向了lst指向的空间,这样,lt...: 当函数定义中的默认参数赋值为可变对象的时候,PyCharm会自动检测并加以提示,如下所示: 点击“more...”...该检查检测何时在参数的默认值中检测到列表或字典等可变值。默认参数值只在函数定义时计算一次,这意味着修改参数的默认值将影响函数的所有后续调用。 如果函数默认参数使用不可变对象又会怎样呢?
领取专属 10元无门槛券
手把手带您无忧上云