优雅编程之这样使用对象,你就“正常”了(三十二)

开心一笑

【一个四岁的男孩亲了三岁的女孩一口!
女孩对男孩说:“你亲了我可要对我负责啊。”
男孩成熟地拍了拍女孩的肩膀,笑着说:“你放心,我都四岁了,又不是一两岁的小孩子了” 】

**提出问题******

项目中如何使用对象???

解决问题

温馨图片

考虑用静态工厂方法代替构造器

例:

public static Boolean valueOf(boolean b) {
    return (b ? Boolean.TRUE : Boolean.FALSE);
}

静态方法和构造器相比优势:

  • 静态方法有名称,构造器没有:一个类只能有一个带有指定签名的构造器。如果需要2个,它们的参数列表只在参数类型的顺序上有所不同。这并不是个好主意。

  • 静态方法不必在每次调用它们的时候都创建一个新的对象。

  • 静态方法可以返回原返回类型的任何子类型的对象。例如:Java Collections的集合接口有32个便利实现,每种便利实现都对应一个类。

  • 静态方法在创建参数化类型实例的时候,它们使代码变得更加简洁。

    Map<String,List<String>> m = new HashMap<String,List<String>>();

    //以后工作就用这种方法了,不过遗憾的告诉大家目前jdk没改类似方法
    Map<String,List<String>> m = HashMap.newInstance();

静态方法的缺点:

  • 类如果不含公有的或者受保护的构造器,就不能被子类化。不能子类化在某些情况下是无法接受的,但是,这样也有好处:策略模式教导我们应该多用组合而不是继承,当一个类不能子类化后,组合将是你唯一的选择。
  • 静态工厂方法和其他静态方法本质上并没有区别

依靠一些约定俗称的名称分辨基本的静态工厂方法。具体包括:

valueOf()       //方法返回的实例与参数具有相同的值
of()            //valueOf 的简化表示
getInstance()   //返回的实例通过参数来描述
newIntance()    //返回一个与现有实例不同的全新实例
getType()       //Type 表示返回的对象类型,如 getString() 返回一个String对象
newType()       //返回一个全新的 Type 类型的对象

总结:

静态方法通常更加合适,因此切记第一方法就是提供共有的构造器,而不先考虑静态工厂。


遇到多个构造器参数时要考虑构造器

重叠构造器模式:第一个构造器只有一个必要参数,第二个有一个可选参数,第三个有两个,以此类推,最后一个构造器有全部的可选参数。创建实例的时候,选择最短的列表参数的构造器,当有许多参数的时候,客户端代码会很难编写

参考高手文章:http://macrochen.iteye.com/blog/1113031

解决方法:采用构建器(Builder)

public Class A{  
    private int a;  
    private int b;  
    private int c;  
    private int d;  
    public static class Builder{  
        // 这些是必要参数
        private final int a;  
        private final int b;  
        //这些是可选参数
        private int c;  
        private int d;  
  
        public Builder(int a, int b){  
            this.a=a;  
            this.b=b;  
        }  
  
        public Builder setC(int c){  
            this.c = c; 
            //注意是这里,这里,看过来,看过来 
            return this;  
        }  
  
        public Builder setD(int d){  
            this.d=d;  
            return this;  
        }  
  
        public A build(){  
            return new A(this);  
        }  
  
        private A(Builder builder){  
            a = builder.a;  
            b = builder.b;  
            c = builder.c;  
            d = builder.d;  
        }  
}  
使用:  
A a = new A.Builder(1, 2).setC(3).setD(4).build();  

总结:

如果类的构造器或者静态工厂中具有多个参数, 设计这种类时, Builder模式就是一种不错的选择. 特别是大多数参数都是可选的时候. 与使用传统的重载构造器模式相比, 使用Builder模式的客户端将更易于阅读和编写.


用私有构造器或者枚举类型强化Singleton属性

Singleton指被实例化一次的类。

参考高手文章:http://www.cnblogs.com/rilley/archive/2012/10/24/2737597.html

例:

//这种写法存在缺陷,可以利用反射的方式来实例化多个不同的实例
//序列化和反序列换的时候也会出现多个不同的实例
public class Elvis {
  public static final Elvis INSTANCE = new Elvis();
  private Elvis {}
}

参考高手文章:http://blog.csdn.net/huangyuan_xuan/article/details/52193006

或者:

public class Elvis {
  private staic final Elvis INSTANCE = new Envis();
  private Elvis() {}
  private static Elvis getInstance() { 
        //开过来,这里很重要
        return INSTANCE; 
    }
}

或者:

public enum Elvis{ 
    INSTANCE; 
    public void invoke(){...} 
} 

参考高手文章:http://callmegod.iteye.com/blog/1474441

public enum MaYun {
    himself; //定义一个枚举的元素,就代表MaYun的一个实例
    private String anotherField;
    MaYun() {
        //MaYun诞生要做的事情
        //这个方法也可以去掉。将构造时候需要做的事情放在instance赋值的时候:
        /** himself = MaYun() {
        * //MaYun诞生要做的事情
        * }
        **/
    }

    public void splitAlipay() {
        System.out.println(“Alipay是我的啦!看你丫Yahoo绿眉绿眼的望着。。。”);
    }
}
Call:MaYun.himself.splitAlipay();

单元素的枚举类型已经成为实现Singleton的最佳方法。

枚举:很好,不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。但是失去了类的一些特性,没有延迟加载,用的人也太少了~~

以后多推广推广单元素枚举这种更好的单例实现方式。在项目中的代码开始修改实施。


通过私有构造器强化不可实例化的能力
  • 对只有静态方法和域的类,主要用于把基本类型的值或数据类型上的相关方法组织起来(Math,Arrays),可以通过Collections的方法把实现特定接口的对象上的惊天方法组织起来,可以利用这种类把final类上的方法组织起来,以取代扩展该类的做法。
  • 此工具类是不希望被实例化的,实例化对他么有任何意义。然后我们如果不提供构造器,jvm会自己提供,那还是会被实例化,那么我们只要在类中提供一个私有的构造器就可以了,并添加注释说明。
    这样带来的问题是不能子类化,因为子类要求要求super父类的构造函数。

避免创建不必要的对象

一般来说,最好能重用对象,而不是在每次需要的时候,就创建一个相同功能的对象,如果对象是不可变的,他就始终可以被重用。

例如
//"ay & al" 本身就是一个对象,这样写的话,頻繁调用会造成成千上万不必要的String实例
String s = new String("ay & al");

改进

String s = "al & ay";

对于同时提供的静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法,而不是构造器,以避免创建不必要的对象。

例如

Boolean.valueOf(String)

优于

Boolean(String)

要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱。

例如

public static void main(String[] args){
    Long sum = 0L;
    for(long i=0;i<Integer.MAX_VALUE;i++){
        sum + = i;//在这里不断的进行装箱和拆箱工作
    }
    System.out.println(sum);
}

消除过期的对象引用

清空引用对象应该是一种例外, 而不是一种规范行为

以下三种情况要考虑会发生内存泄露:

  • 类自己申请内存管理
  • 缓存,易忘记管理,如WeakHashMap可以自动处理没有被外部引用的缓存项。一般利用后台线程定时清理,也可以类似LinkedHashMap使用removeEldestEntry在添加条目时清理。对于复杂的缓存,必须直接使用java.lang.ref
  • 监听器和其他回调,回调此时可以做成弱引用。

只要是类自己管理内存, 程序员就应该警惕内存泄露的问题.

读书感悟

来自杰克·凯鲁亚克《在路上》

  • 真正不羁的灵魂不会真的去计较什么,因为他们的内心深处有国王般的骄傲。
  • 我还年轻,我渴望上路。带着最初的激情,追寻着最初的梦想,感受着最初的体验,我们上路吧。
  • 在路上,我们永远年轻,永远热泪盈眶。
  • 我们还有更长的路要走,不过没关系,道路就是生活。
  • “我一辈子都喜欢跟着让我有感觉有兴趣的人,因为在我心目中,真正的人都是疯疯癫癫的,他们热爱生活,爱聊天,不露锋芒,希望拥有一切,他们从不疲倦,从不讲些平凡的东西,而是像奇妙的黄色罗马烟火那样,不停地喷发火花。

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,192评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,186评论 1 303
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,844评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,471评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,876评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,891评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,068评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,791评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,539评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,772评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,250评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,577评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,244评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,146评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,949评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,995评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,812评论 2 276

推荐阅读更多精彩内容