*1、考虑静态工厂方法(static factory method)代替构造器?!优势?不足?

服务提供者架构:

1、服务接口(Service Interface) -- 提供者实现的;

2、提供者注册API(Provider Registration API)--系统用于注册实现,让客户端访问它们;

3、服务访问API(Service Access API)--客户端用于获取服务的实例;[它是“灵活的静态工厂”,构成了服务提供者架构的基础!]

*4、服务提供者接口(Service Provider Interface)--这些提供者负责创建其服务实现的实例

[如果没有Service Provider Interface,实现就按照类名称注册,并通过反射方式进行实例化。

对于JDBC来说,

Connection就是它的服务接口,

DriverManager.registerDriver是提供注册API,

DriverManager.get Connection是服务访问API,

Driver就是服务提供者接口]

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

*3、用私有构造器or枚举类型强化Singleton属性

4、通过私有构造器强化不可实例化的能力

5、避免创建不必要的对象

*6、消除过期的对象引用

// Can you spot the "memory leak"?
public class stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }

    /**
     * Ensure space for at least one more element, roughly
     * doubling the capacity each time the array needs to grow.
     */
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2*size+1);
    }
}

BUG:“内存泄漏”,随着垃圾回收器活动的增加,或者由于内存占用的不断增加,程序性能的降低逐渐表现出来。极端情况、

会导致磁盘交换(Disk Paging),甚至导致程序报错(OutOfMemoryError)--少见!

eg:如果一个栈先是增长,再收缩,那么从栈中弹出来的对象将不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,它们也

不会被回收。因为:栈内部维护着对这些对象的过期引用(obsolete reference)--即永远也不会再被解除的引用。本例中,elements

数组的“活动部分(active portion)”之外的任何引用都是过期的。活动部分指:elements中下标小于size的那些元素。

fix bug:一旦对象引用过期,需要清空这些引用。即修改pop方法,如下;

    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference.
        return result;
    }

好处:

1、解决BUG出现的内存长期占用,降低性能;

2、如果它们以后又被错误的解除引用,程序就会抛出NullPointerException异常,而不是悄悄继续运行下去!

/**

* 1、只要是自己管理内存,程序员就应该警惕内存泄露问题;

* 2、缓存;--把对象引用放到缓存中,它就很容易被遗忘掉;

[修复:只要在缓存之外存在某个项的键的引用,该项就有意义,那么就可以用WeakHashMap代表缓存!

“缓存项的生命周期是否有意义”--不容易确定。LinkedHashMap类利用它的removeEldestEntry方法!

更加复杂的缓存,必需直接使用java.lang.ref!]

* 3、监听器 & 其他回调

[eg:如果你实现一个API,客户端在这个API中注册回调,却没有显式地取消注册,那么除非你采取某些动作,否则

它们就会聚集。确保回调立即被当作垃圾回收的最佳方法是只保存它们的弱引用(weak reference),例如,只将它们

保存成WeakHashMap中的键。]

**/

7、避免使用终结方法?(即finalizer)

“不要把终结方法当作是C++析构器的对应物!(构造器)”

C++:析构器(destructors)回收一个对象所占用的资源,是构造器所必需的对应物; --也可以回收其他的非内存资源

Java:当一个对象变得不可到达时,垃圾回收机制会回收与该对象相关联的存储空间;--用try-finally实现类似工作

----------------------------

Effective Java 

  -- Second Edition (James Gosling)

----------------------------

[Java] 一、对象的创建 & 销毁的更多相关文章

  1. java中对象的创建过程

    public class Test1 { public static void main(String[] args) { new B(); System.out.println("---- ...

  2. Java虚拟机-对象的创建和访问

    一.对象的创建: 创建对象在java上面是很简单的,使用new关键字就可以了,但是其实在虚拟机中,java对象的创建是一个复杂的过程. 当java虚拟机遇到一个new的指令的时候,对象创建的程序正式启 ...

  3. 【Java】对象的创建过程

    一.对象的创建过程 1.首次创建对象时或该类静态方法/静态域首次被访问时,JAVA解释器查找该类的路径,定位该类的class文件 2.载入该类的class文件,有关静态初始化的所有动作执行,但是只执行 ...

  4. java面试-对象的创建、内存布局、访问定位

    一.对象的创建 1.虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的 ...

  5. 深入理解java虚拟机---对象的创建过程(八)

    1.对象的创建过程 由于类的加载是一个很复杂的过程,所以这里暂时略过,后面会详细讲解,默认为是已加载过的类.着重强调对象的创建过程. 注意: 最后一步的init方法是代码块和构造方法. 以上是总图,下 ...

  6. java学习笔记——java中对象的创建,初始化,引用的解析

    如果有一个A类. 1.例如以下表达式: A  a1 = new A(); 那么A是类,a1是引用.new A()是对象.仅仅是a1这个引用指向了new A()这个对象. 2.又如: A  a2; A代 ...

  7. java String对象的创建(jvm).

    本人目前也开始学习虚拟机,在java中,有很多种类型的虚拟机,其中就以sum公司(当然现在已经是oracle了)的虚拟机为例,介绍可能在面试的时候用到的,同时对自己了解String有很大帮助,这里仅仅 ...

  8. Java中 对象的创建于调用

    Main方法是程序的主入口,想要用某个方法必须在main方法中调用 创建对象: 类名 对象名 = new 类名(); 使用对象访问类中的成员: 对象名.成员变量: 对象名.成员方法(); 成员变量的默 ...

  9. [ Java学习基础 ] Java对象的创建和销毁

    类实例化可生成对象,实例方法就是对象方法,实例变量就是对象属性.一个对象的生命周期包括三个阶段:创建.使用和销毁. 创建对象 创建对象包括两个步骤:声明和实例化. 声明 声明对象与声明普通变量没有区别 ...

随机推荐

  1. Directx11学习笔记【四】 封装一个简单的Dx11DemoBase

    根据前面两个笔记的内容,我们来封装一个简单的基类,方便以后的使用. 代码和前面类似,没有什么新的内容,直接看代码吧(由于代码上次都注释了,这次代码就没怎么写注释o(╯□╰)o) Dx11DemoBas ...

  2. C#中的Virtual

    在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtual. 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new ...

  3. SRM 620 D2L3: RandomGraph, dp

    称号:http://community.topcoder.com/stat? c=problem_statement&pm=13143&rd=15853 參考:http://apps. ...

  4. uploadify控制 上传图片到百度云存储

    最近使用uploadify 控制图片上传到百度网盘....总的想法是 招待会uploadify获取文件传入后台,调用百度云存储api上传到百度网盘,返回url 联系.送存储在数据库中的链接.因此,我们 ...

  5. TCP/IP 网络精讲:开宗明义及第一课

    内容简介 1.课程大纲 2.第一部分第一课:互联网历史 3.第一部分第二课预告:互联网的创立,OSI七层模型 课程大纲 我们将带大家一起来学习很多网络方面的技能,向大家介绍TCP/IP的基础知识点.你 ...

  6. Codeforces 437E The Child and Polygon(间隔DP)

    题目链接:Codeforces 437E The Child and Polygon 题目大意:给出一个多边形,问说有多少种切割方法.将多边形切割为多个三角形. 解题思路:首先要理解向量叉积的性质,一 ...

  7. 经FreeMarkerclasspath加载方式生成静态页面

    package htmlskin; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundExc ...

  8. javascript 比量str今天的日期是,参数diff

    function isToday(str) { var d = new Date(str.replace(/-/g, "/")); var todaysDate = new Dat ...

  9. UIButton 文字图片排列

    UIButton缺省值是:图画-文字水平,所以我们并不需要调整. 1.写作-图画 水平显示,以前的文本,图片后再次 [btn setTitleEdgeInsets:UIEdgeInsetsMake(0 ...

  10. 跨容器Hybrid离线组件方案

    关键词:跨容器.Hybrid.离线 摘要:今天主要讨论的是离线组件跨容器方案,想了解在线页面如何跨webview容器,可以看 http://www.cnblogs.com/yexiaochai/p/5 ...