Desktop Window Manager为什么会无缘无故流鼻血崩溃

Java学习(9)
转自:http://my.oschina.net/jasonultimate/blog/166810
不可变对象(immutable objects),后面文章我将使用immutable objects来代替不可变对象!
那么什么是immutable objects?什么又是mutable Objects呢?
immutable Objects就是那些一旦被创建,它们的状态就不能被改变的Objects,每次对他们的改变都是产生了新的immutable的对象,而mutable Objects就是那些创建后,状态可以被改变的Objects.
举个例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。
但有的时候String的immutable特性也会引起安全问题,这就是的原因!
immutable objects 比传统的mutable对象在多线程应用中更具有优势,它不仅能够保证对象的状态不被改变,而且还可以不使用锁机制就能被其他线程共享。
实际上JDK本身就自带了一些immutable类,比如String,Integer以及其他包装类。为什么说String是immutable的呢?比如:java.lang.String 的trim,uppercase,substring等方法,它们返回的都是新的String对象,而并不是直接修改原来的对象。
如何在Java中写出Immutable的类?
要写出这样的类,需要遵循以下几个原则:
1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
当然不完全遵守上面的原则也能够创建immutable的类,比如String的hashcode就不是final的,但它能保证每次调用它的值都是一致的,无论你多少次计算这个值,它都是一致的,因为这些值的是通过计算final的属性得来的!
另外,如果你的Java类中存在很多可选的和强制性的字段,你也可以使用建造者模式来创建一个immutable的类。
下面是一个例子:
public final class Contacts {
private final S
private final S
public Contacts(String name, String mobile) {
this.name =
this.mobile =
public String getName(){
public String getMobile(){
我们为类添加了final修饰,从而避免因为继承和多态引起的immutable风险。
上面是最简单的一种实现immutable类的方式,可以看到它的所有属性都是final的。
有时候你要实现的immutable类中可能包含mutable的类,比如java.util.Date,尽管你将其设置成了final的,但是它的值还是可以被修改的,为了避免这个问题,我们建议返回给用户该对象的一个拷贝,这也是Java的最佳实践之一。下面是一个创建包含mutable类对象的immutable类的例子:
public final class ImmutableReminder{
private final Date remindingD
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() & System.currentTimeMillis()){
throw new IllegalArgumentException(&Can not set reminder” +
“ for past time: & + remindingDate);
this.remindingDate = new Date(remindingDate.getTime());
public Date getRemindingDate() {
return (Date) remindingDate.clone();
上面的getRemindingDate()方法可以看到,返回给用户的是类中的remindingDate属性的一个拷贝,这样的话如果别人通过getRemindingDate()方法获得了一个Date对象,然后修改了这个Date对象的值,那么这个值的修改将不会导致ImmutableReminder类对象中remindingDate值的修改。
使用Immutable类的好处:
1)Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享
2)Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享
3)Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用
4)Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
immutable也有一个缺点就是会制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,字符串就是一个典型的例子,它会创造很多的垃圾,给垃圾收集带来很大的麻烦。当然这只是个极端的例子,合理的使用immutable对象会创造很大的价值。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7050次
排名:千里之外
原创:36篇
(1)(1)(1)(6)(5)(2)(4)(3)(1)(5)(4)(2)(1)(1)(1)python学习mutable and immutable
python的数据类型分为mutable(可变) 和 immutable (不可变) mutable : list ,dict inmutable : int , string , float ,tuple... mutable和immutable 字面意思理解就是说数据可变和数据不可变 由于
14:44&&&[]
;&&&&&&&&&Immutable &&&&Immutable pattern 也是多线程设计时候的一个准则,初学多线程把数据能准确分辨会变和不会变就可以前面两种模式
13:05&&&[]
  不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:    1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象    2.线程
16:07&&&[]
本文引用至: 条件 循环
python中的条件语句格式没有什么太多要说的内容. 就是if...elif...else 这3个语句结构.就比如这样的:
num = float(input(&Enter a number: &)) if num & 0: print
03:37&&&[]
/second-some-suffix first/second-some-suffix-some-suffix
path 这个参数在函数里面被改变了,然后这个改变传到了外面,就这样灾难开始了。 这种代码一旦发生就很难调试,让我们拥抱 immutable 吧。
但如果把 && 改为 += 就不会出现这个问题,我不太
21:03&&&[]
《Problem Solving with Algorithms and Data Structures using Python》 的学习笔记和课后作业(一)
包含本书第一章,第二章。
这本书的 豆瓣评分 高达9.3,python作为接近算法伪码的一种脚本语言,其实用它写算法是极好的
06:54&&&[]
11:53&&&[]
Dict Hash Table
在Python中Key/Value结构的哈希表叫做Dict[字典] 字典使用{}定义,内容是一系列的Key:Value。空的字典用{}表示 字符串、数字、元组都可以作为字典的key.
## Can build up a dict by starting
21:26&&&[]
Python类与面向对象 & &程序=指令+数据 (或算法+数据结构)。代码可以选择以指令为核心或以数据为核心进行编写。 & &两种范型 & & & &(1)以指令为核心:围绕“正在发生什么”进行编写(面向过程编程
21:53&&&[]
python中的and和or 4.6. and 和 or 的特殊性质 在Python 中,and 和 or 执行布尔逻辑演算,如你所期待的一样,但是它们并不返回布尔值;而是,返回它们实际进行比较的值之一。
例 4.15. and 介绍 &&& 'a' and 'b'&nbsp
15:00&&&[]
Python中对于对象的赋值都是引用,而不是拷贝对象(Assignment statements in Python do not copy objects, they create bindings between a target and an object.)。对于可变对象来说,当一个改变的
18:41&&&[]
Python and Collective Intelligence KeyError: href:/questions//python-and-collective-intelligence-keyerror-href https
09:03&&&[]您所在的位置: &
阐述PyString Object对象源代码
阐述PyString Object对象源代码
在对PyIntObject的分析中,我们看到了Python中的具有不可变长度数据的对象(定长对象)。在Python中,还大量存在着另一种对象。
Python也被称为是一门非常透彻的语言,在当初设计者当初设计它的时候,大体的指导思想,就是对于一个特定的问题,只要有一种最好的方法来解决就OK了,下面对Python PyStringObject对象说明。
与定长对象不同,对于变长对象而言,对象维护的数据的长度在对象定义时是不知道的。对于PyIntObject来说,其维护的数据的长度在对象定义时就已经确定了。是一个long变量的长度;而可变对象维护的数据的长度只能在对象创建时才能确定,考虑一下,我们只能在创建一个字符串或一个列表时才知道它们所维护的数据的长度,在此之前,对这个信息,我们一无所知。
在变长对象中,实际上还可分为可变对象(mutable)和不可变对象(immutable),可变对象是在对象创建之后,其维护的数据的长度还能变化的对象。比如一个list被创建后,可以向其中添加元素或删除元素。
这些操作都会改变其维护的数据的长度;而不可变对象所维护的数据在对象创建之后就不能再改变了,比如Python中的string和tuple,它们都不支持添加或删除的操作。本章我们将研究Python变长对象中的不可变对象――字符串对象。
在Python中,PyStringObject是对字符串对象的抽象和表示。PyStringObject对象是一个拥有可变长度内存的对象,这一点非常容易理解,因为对于表示”Hi”和”Python”的两个不同的PyStringObject对象,其内部需要的保存字符串内容的内存空间显然是不一样的。
但同时,PyStringObject对象又是一个不变对象(Immutable)。当创建了一个PyStringObject对象之后,该对象内部维护的字符串就不能再被改变了。这一点特性使得PyStringObject对象能作为PyDictObject的键值,但同时也使得一些字符串操作的效率大大降低,比如多个字符串的连接操作。
PyStringObject对象的声明如下: [stringobject.h]& &typedef&struct&{&&&&PyObject_VAR_HEAD&&&&long&ob_&&&&int&ob_&&&&char&ob_sval[1];}&PyStringObject;&
在PyStringObject的定义中我们看到,在PyStringObject对象的头部实际上是一个PyObject_VAR_HEAD,其中有一个ob_size变量保存着对象中维护的可变长度内存的长度。虽然在PyStringObject的定义中,ob_sval是一个字符的字符数组。
但是ob_sval实际上是作为一个字符指针指向了一段内存,这段内存保存着这个字符串对象所维护的实际字符串,显然,这段内存不会只是一个字节。而这段内存的实际长度(字节),正是由ob_size来维护,这个机制是Python中所有拥有可变长度内存的对象的实现机制。比如对于PyStringObject对象”Python”,ob_size的值就是6。
同C中的字符串一样,内部维护的字符串在末尾必须以’\0’结尾,但是由于字符串的实际长度是由ob_size维护的,所以PyStringObject表示的字符串对象中间是可能出现字符’\0’的,这一点与C语言中不同,因为在C中。只要遇到了字符’\0’,就认为一个字符串结束了。所以,实际上,ob_sval指向的是一段长度为ob_size+1个字节的内存,而且必须满足ob_sval[ob_size] = ‘\0’。
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
想要理解大数据,使之更贴近大多数人,最重要的手段的之一就是数
随着云计算、物联网、大数据、移动互联网的大发展,你应该知道这些。
讲师: 10人学习过讲师: 8人学习过讲师: 14人学习过
新手程序员关注编程趋势就好比股民时刻关心股价走向一
AngularJS是很多Web开发人员在打造单页面应用程序时的
针对大数据来说,2016年将是令人振奋的一年。智能算法
本书是Inside Microsoft SQL Server 2000的作者Kalen Delaney的又一经典著作,是Inside Microsoft SQL Server 2005系列四本著作
51CTO旗下网站本文由&– 栗子蜀黍原创翻译,转载请看清文末的转载要求,欢迎参与我们的!
简介:本文主要介绍java中不可变类的相关知识,文章中大部分内容来自博客,博客地址见以下链接
小编不去纠结原文中,为什么标题是immutable class,正文却上来便问what is immutable object。相信,学java的人,都应该知道class和object确切表示什么意思。
class:java中class确切的表示为一个类
object:java中object确切的表示为一个对象,也称为类的实例
其实,如果一个类被设计成不可变的类,那么这个类的实例化对象也是不可变的。
不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。
那么,什么是不可变对象?
一旦一个类的实例化对象被创建并初始化,那么它就不可以被改变。我们可以调用访问器方法(getter),复制对象,或者传递对象,但是不允许任何方法改变这个对象的状态。包装类(e.g.Integer或Float)和String类是不可变类的代表。
访问器方法(accessor method):对成员变量做出访问的方法,e.g.getter()方法。
修改器方法(mutator method):对成员变量做出修改的方法,e.g.setter()方法。
定义一个不可变类
如果我们要自己创建一个不可变类,需要遵守下面的规则:
将成员变量(field:在一些书中也翻译为域)声明成final并在构造器中初始化。
对于基本类型的成员变量,用final修饰,一旦它被初始化,就不能被改变了。而对于引用类型的成员变量,不能够改变它的引用。
成员变量如果被声明称final,那么构建对象时,必须要初始化这样的域
引用类型是可变的,我们需要采取一些措施来保证它的不可变性。
为什么?如果我们只是声明了一个final的可变引用类型,那么这个引用可以去引用外部的类,或者被其他外部类引用。在这种情况下,我们要做到:
1.这些方法不会改变这些可变对象中的内容
2.不要将这些引用分享到外部供其他类使用,例如,如果对成员变量的引用是可以被其他类改变的,那么这些外部类就可以改变这个类中的内容。
3.如果必须要返回一个引用,那么就返回一个对象的深度拷贝,这样尽管返回的对象内容改变了,但也保存着原始的内容。
只提供访问器方法(i.e. getter方法)不提供修改器方法(i.e.setter方法)
如果一定要改变这个对象的内容,那就创建一个新的不可变对象内容做相应的修改,返回修改后的对象的引用
声明类是final的。如果一个类可以被继承,那么它子类就可以重载它的方法,并且修改成员变量
Java API中不可变类的例子
让我们来回顾一下String类,用它来理解上述的几个方面在String类实现中的体现:
所有在Stirng类中成员变量都被声明成private,这些成员变量都在构造器中在构建对象时被初始化。
trim concat substring 都可以改变String的对象,为了保证String的不可变性,这些方法都返回的是一个改变相应内容后新的对象。
string类被声明称final,所以任何类都不能继承,重载它的方法。
自己实现一个不可变类
接下来我们自己实现一个不可变类ImmutableCircle。
//ImmutableCircle.java
// Point is a mutable class
class Point {
private int xPos, yP
public Point(int x, int y) {
public String toString() {
return "x = " + xPos + ", y = " + yP
int getX() { return xP }
int getY() { return yP }
// ImmutableCircle is an immutable class – the state of its objects
// cannot be modified once the object is created
public final class ImmutableCircle {
private final P
public ImmutableCircle(int x, int y, int r) {
center = new Point(x, y);
public String toString() {
return "center: " + center + " and radius = " +
public int getRadius() {
public Point getCenter() {
// return a copy of the object to avoid
// the value of center changed from code outside the class
return new Point(center.getX(), center.getY());
public static void main(String []s) {
System.out.println(new ImmutableCircle(10, 10, 20));
// other members are elided ...
上面的程序运行之后,打印:
center: x = 10, y = 10 and radius = 20
上面的程序体现了不可变类的以下几点:
这个类被声明成final,不可以被继承,也不可以重载它的方法
这个类的成员变量都是final并且是私有的
因为成员变量center是一个引用类型,是可变的,所以在他的getter方法中,返回的是对point对象的拷贝
设计一个不可变的类最关键的一点:
要注意引用类型的成员变量,如果成员变量的类型是可变的引用类型,就必须要采取必要的措施来保护这个成员变量不会被修改
不可变类不足的地方
不可变对象同样也有不足的地方。为了保证不可变性,不可变类中的方法会创建出一定量的对象的拷贝。例如,在上面的代码中,每次调用getcenter方法都会新建并返回一个point对象的拷贝。而假如我们只需要调用一次,返回一个point对象,就没必要费尽心神的去设计一个不可变类,仅仅只需要一个可变的immutablecircle类就可以了。
String类在很多应用场景中都会用到,如果我们调用String类中trim,concat,或者是在循环中调用substring方法,都会创建一个新的临时String对象。同时,java也提供了Stringbuffer和Stringbuilder的可变类。他们同String一样,但是却可以改变这个对象的内容。所以,我们可以根据不同的场景使用String类或者Stringbuffer/Stringbuilder类。
总结,文章的最后还是那句话,要根据自己的实际需要,去设计代码,而不要过度设计。
译文链接:
英文原文:
翻译作者:&– 栗子蜀黍
[&转载必须在正文中标注并保留原文链接、译文链接和译者等信息。]
在文章中找不到问题答案?您还可以
热门栏目订阅请问可变对象和不可变对象的本质区别,如NSString和...-学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
> 信息中心 >
请问可变对象和不可变对象的本质区别,如NSString和...
来源:互联网 发表时间: 13:38:08 责任编辑:李志喜字体:
为了帮助网友解决“请问可变对象和不可变对象的本质区别,如NSString和...”相关的问题,学网通过互联网对“请问可变对象和不可变对象的本质区别,如NSString和...”相关的解决方案进行了整理,用户详细问题包括:RT,我想知道:请问可变对象和不可变对象的本质区别,如NSString和...,具体解决方案如下:解决方案1: 内存分配固定. 可以任意复制多份:1,但这个就见仁见智了。其他当然还有一些函数式编程提倡的好处,比如代码清晰等等,不同线程之间不需要加锁解锁这就是函数式编程中的“变量不变”的特性,不需要扩充2不可变对象有几个好处
1个回答1个回答3个回答1个回答2个回答1个回答4个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答
相关文章:
最新添加资讯
24小时热门资讯
Copyright © 2004- All Rights Reserved. 学网 版权所有
京ICP备号-1 京公网安备02号

我要回帖

更多关于 无缘无故流鼻血 的文章

 

随机推荐