美文网首页
避免创建不必要的对象--EffectiveJava小结(5)

避免创建不必要的对象--EffectiveJava小结(5)

作者: 冰鱼飞鸟 | 来源:发表于2018-08-01 23:44 被阅读0次

尽量重用对象,而不是重新创建。

一.重用不可变对象

不可变对象,始终可以被重用。
如String

//尽量用,多次调用不会重复创建对象
String s = "";
//而不是,调多少次就创建多少次对象
String s2 = new String("");

另外调用静态工厂方法优于调用构造器。
如Boolean.valueOf(String); 优于new Boolean(String)
因为前者会返回Boolean中缓存的true和false对象,避免重复创建。

二.重用适配器/视图对象

适配器/视图对象是指这样一个对象:它把功能委托给一个后备对象,从而为后备对象提供一个可以替代的接口。
由于其除了后备对象外没有其他状态信息,所以针对某个给定对象的特定适配器而言,它不需要创建多个适配器实例。

这句话咋一看难以理解,没有代入感。下面以HashMap的keySet为例进行理解

final class KeySet extends AbstractSet<K> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<K> iterator()     { return new KeyIterator(); }
        public final boolean contains(Object o) { return containsKey(o); }
        public final boolean remove(Object key) {
            return removeNode(hash(key), key, null, false, true) != null;
        }
        public final Spliterator<K> spliterator() {
            return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }
    
    final class KeyIterator extends HashIterator
        implements Iterator<K> {
        public final K next() { return nextNode().key; }
    }
    
    final Node<K,V> nextNode() {
            Node<K,V>[] t;
            Node<K,V> e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            if ((next = (current = e).next) == null && (t = table) != null) {
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }

这个KeySet类就是一个适配器/视图。

根据视图这个名字我们就可以初步理解为KeySet这个类本身并没有存储数据,其数据来源都是其后备对象即HashMap。

可以看到KeySet只有方法没有自己的属性,并且方法中使用的都是HashMap中的属性。程序调用KeySet的方法实际是访问了这个HashMap的方法或属性。

这样看来如果为同一个HashMap创建多个KeySet对象并没有意义。因为修改了任何一个KeySet其实都是修改的这个HashMap。完全没有必要创建用处完全相同的多个KeySet。

至此把上面那句话用HashMap,KeySet代入来说的话就是

HashMap中的KeySet对象把KeySet的功能委托给这个HashMap对象来完成,从而为HashMap提供一个可以替代的接口。由于这个KeySet除了HashMap这个后备对象外,没有其他状态信息,所以针对一个给定的HashMap的KeySet而言,不需要创建多个KeySet实例。

三.注意自动装箱导致的创建多余对象

四.不需要过于追求性能而尽可能不创建对象。
实际上小对象的创建和回收代价很小,如果创建新的对象可以增加程序的清晰性,简洁性和功能性,那通常是件好事。
如为了保护原有数据而拷贝对象导致的重复创建。这时候重用对象可能会付出更大的代价。

相关文章

  • 避免创建不必要的对象--EffectiveJava小结(5)

    尽量重用对象,而不是重新创建。 一.重用不可变对象 不可变对象,始终可以被重用。如String 另外调用静态工厂方...

  • 5.避免创建不必要的对象

    一般来说,如果能重用对象,尽量重用对象,而不是创建一个相同的对象.如果对象是不可变的,它始终就应该被重用. 作者举...

  • 5.避免创建不必要的对象

    最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。 如果对象是不可变(immutable),它就始终...

  • 条目6:避免创建不必要的对象

    避免创建不必要的对象 避免通过构造函数创建字符串 避免使用String.match方法做正则匹配 避免在循环中频繁...

  • 避免创建不必要的对象

    在编码中尽量减少大对象的使用,创建对象的成本是非常高的。举个栗子: 代码块一 代码块二 在代码块一中我们使用的是l...

  • 避免创建不必要的对象

    第五条:避免创建不必要的对象 1. 简介 一般来说,我们最好的做法是重用对象,而不是每次使用都new出一个新的相同...

  • 避免创建不必要的对象

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

  • 避免创建不必要的对象

    记住一个原则:能重用对象就不要每次都创建一个新的对象。例一: 字符串常量在JVM常量池中储存。 例二:对于同时提供...

  • 避免创建不必要的对象

    一、错误做法 二、正确做法

  • Android 如何提高代码质量?

    避免创建不必要的对象,尽可能避免频繁的创建临时对象,例如在for循环内,减少GC的次数。 尽量使用基本数据类型代替...

网友评论

      本文标题:避免创建不必要的对象--EffectiveJava小结(5)

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