美文网首页
第二章创建和销毁对象

第二章创建和销毁对象

作者: 后来丶_a24d | 来源:发表于2020-03-11 11:03 被阅读0次

目录

  • 创建和销毁对象
    • 静态工厂方法
    • 遇到多个构造器参数时要考虑使用构造器
    • 用私有构造器或者枚举类型强化 Singleton 属性
    • 通过私有构造器强化不可实例化的能力
    • 避免创建不必要的对象
    • 清除过期的对象引用
    • 避免使用终结方法
    • 使用依赖注入取代硬连接资源
    • 使用 try-with-resources 语句替代 try-finally 语句

创建和销毁对象

静态工厂方法(就是类里面的static方法创建对象)代替构造器

优点:

  1. 静态工厂方法有名字;
  2. 不必要每次调用的时候都创建一个新的对象。
  3. 返回原返回类型的任何子类型对象。
  4. 创建参数化类型实例的时候使代码变得更加简洁。

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

Builder 模式,代码易读,模拟了具名的可选参数,build 方法可检验约束条件。 builder 可以自动填充某些域,比如每次创建对象的时自动增加序列号。

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

public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    //私有化
    private Elvis() { … }
    public void leaveTheBuilding() {…}
}

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

希望一个类不能被实例化,则私有化构造方法,比如一个很多都是static方法的类,肯定不希望被实例化

避免创建不必要的对象

  • string类具有不可变性(内部状态不会被改变),每个string类的方法比如replace都是返回new String, String s指向一个内存块,当s = ‘abc’在常量池已有时不会再创建,而是指定这块已有的区域。
  • 不可变有点, map的key是String的,string不可变则意味着每次hashcode是一样的,不需要重复计算。不可变则线程安全。
String s1 = "string";

String s2 = new String("string");  // don‘t do this

  • 当心无意识的基本类型自动装箱,自动装箱类型初始化是null,==的时候小心出问题。能用基本类型就用基本类型,性能提高不少。

清除过期的对象引用

Java 内存泄露可能发生在:

  • 类自我管理内存

    比如在实现 Stack 栈时,弹出栈时,消除对象引用,结束变量的生命周期。

  • 缓存

  • 代码举例, 当我们调用pop方法是,该方法将返回当前栈顶的elements,同时将该栈的活动区间(size)减一,然而此时被弹出的Object仍然保持至少两处引用,一个是返回的对象,另一个则是该返回对象在elements数组中原有栈顶位置的引用。这样即便外部对象在使用之后不再引用该Object,那么它仍然不会被垃圾收集器释放,久而久之导致了更多类似对象的内存泄露。
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];
        }
        private void ensureCapacity() {
            if (elements.length == size)
                elements = Arrays.copys(elements,2*size+1);
        }
    }

改进
public Object pop() {
        if (size == 0) 
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; //手工将数组中的该对象置空
        return result;
    }

避免使用终结方法

  • Java的语言规范中并没有保证该方法会被及时的执行,甚至都没有保证一定会被执行。即便开发者在code中手工调用了System.gc和System.runFinalization这两个方法,这仅仅是提高了finalizer被执行的几率而已。finalizer方法可以作为安全网使用。
  • 提供显式的终止方法,要求类客户端在每个实例不再有用的时候调用这个方法。 Java 中 FileInputStream, FileOutputStream,Timer 和 Connection 都具有终结方法。

使用依赖注入取代硬连接资源

  • 许多类依赖于一个或多个底层资源。例如,拼写检查器依赖于字典。将此类类实现为静态实用工具类并不少见
public class SpellChecker {
    private static final Lexicon dictionary = ...;

    private SpellChecker() {} // Noninstantiable

    public static boolean isValid(String word) { ... }
    public static List<String> suggestions(String typo) { ... }
}
  • 这两种方法都不令人满意,因为他们假设只有一本字典值得使用。在实际中,每种语言都有自己的字典,特殊的字典被用于特殊的词汇表。
  • 静态实用类和单例对于那些行为被底层资源参数化的类来说是不合适的
  • 使用依赖注入
public class SpellChecker {
    private final Lexicon dictionary;

    public SpellChecker(Lexicon dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }

    public boolean isValid(String word) { ... }
    public List<String> suggestions(String typo) { ... }
}

在处理必须关闭的资源时,使用 try-with-resources 语句替代 try-finally 语句。 这会使生成的代码更简洁、更清晰,并且抛出的异常在调试时更有用。


参考文献

相关文章

  • 《Effective Java》学习笔记 第二章 创建和销毁对象

    第二章 创建和销毁对象 何时以及如何创建对象,何时以及如何避免创建对象,如何确保他们能够适时地销毁,以及如何管理对...

  • Effective Java

    第二章 创建和销毁对象 1、静态工厂代替构造器 避免每次都创建对象 可返回任何子类型对象 .from .of .v...

  • EffectJava翻译系列(第一章:创建和销毁对象)

    1.创建和销毁对象 这个章节包含创建和销毁对象,什么时候和怎样创建,什么时候避免创建,如何确保对象在准确的时机销毁...

  • Effective Java Note (对象的创建和销毁)

    Effective Java Note (对象的创建和销毁) 一、对象的创建和销毁 1. 考虑使用静态工厂方法替代...

  • 优雅地创建和销毁对象

    创建和销毁对象概述 何时以及如何创建对象 何时以及如何避免创建对象 如何确保对象适时地销毁 如何管理对象销毁之前必...

  • EffectiveJava 学习记录 一

    第一章 前言 学习摘要 第二章 创建和销毁对象 学习主题 学习摘要 2017/7/4 23:15:43

  • Effective Java 2.0_中文版__Item 1

    文章作者:Tyan博客:noahsnail.com 第二章 这章是关于创建和销毁对象的:什么时候怎样创建它们,什么...

  • effective java 读书笔记

    第二章:创建和销毁对象 第7条:避免使用终结方法 final、finally、finalize的区别: 第三章对所...

  • 创建和销毁对象

    1、何时以及如何创建对象? 2、何时以及如何避免创建对象? 3、如何确保它们能够适时地销毁,以及如何管理对象销毁之...

  • 创建和销毁对象

    避免创建不必要的对象 重用不可变对象和已经的不会被修改的对象 考虑下面的语句String s=new String...

网友评论

      本文标题:第二章创建和销毁对象

      本文链接:https://www.haomeiwen.com/subject/zokqjhtx.html