| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Effective Java 学习笔记(三) -> 正文阅读 |
|
[Java知识库]Effective Java 学习笔记(三) |
条款5:优先使用依赖注入而非硬连接资源很多类需要依赖资源。比如一个SpellChecker类检查拼写依赖于字典:
但是,每个语言都有自己的字典,而且特殊词汇需要特殊字典,只有这一个字典是不行的。当类的行为由硬连接资源参数决定时,静态工具类和单例类并不适用。一种可以满足需求的方法是依赖注入,即当创建新实例时将资源传入构造器内:
虽然依赖注入可以显著提高灵活性和可测试性,它也会让有几千个依赖的大型项目变得很杂乱。当然,使用依赖注入框架(Dagger, Guice, Spring等)可以轻松解决此问题。 条款6:避免创建不必要的对象为了避免资源浪费,我们应尽量重复使用一个对象而非创建一个等价的对象。当对象是不可变对象时总能被重复使用。下面是一个错误的例子:
大家都知道这样是不对的,String不用new,也不应当new出来,不然每次调用都会多出一个多余的没有必要的String实例。正确的做法是:
这保证了当字面量相同时,String对象的重复使用。 我们可以通过使用静态工厂方法(条款1)来避免创建不必要的对象,比如用Boolean.valueof()替代Boolean()。 对于一些创建开销很大的对象来说,我们最好缓存它以达到复用并节约资源的目的。不幸的是,我们难以察觉到这些对象被创建了。例如:
看上去没有问题?实际上每次调用该方法时,都会创建一个Pattern实例且用一次就销毁。每次创建Pattern实例都会有巨大的开销,因为需要把正则表达式编译成有穷自动机。所以,上面的方法应当优化为:
当对象是不可变对象时,显而易见能被安全复用,但还有其他一些情况也能复用,但不是这么的明显,甚至是违反直觉的。比如适配器模式(adapters)或叫视图(view),因为适配器的状态并不会超出原有对象的状态,同一个对象同一个适配器无需创建更多实例。例如,Map的keySet方法返回一个Map对象的Set视图,包含Map的所有key。对于给定的Map对象,每次调用keySet可能返回的是一样的Set实例。 还有一件事——自动装箱也会创建不必要对象。自动装箱模糊了基本类型和装箱类型的界限,但并不是消除了。下面的例子有极大的性能提升空间:
因为用的是Long而不是long,程序创建了2^31个不必要的Long实例!!所以,优先使用基本类型而非装箱类型,且注意意料之外的自动装箱。 本条款主要针对于创建开销很大的对象。开销小的对象创建就创建了,如果能提升程序清晰性、简洁性和功能性反而是很好的事。 除非对象真的是很重量级,开销巨大,不要维护自己的对象池!这样对象池只会起到画蛇添足的作用。一个恰当正确地使用对象池例子是数据库链接,这真的足够重量,所以需要提高对象复用。 本条款与条款50 需要时使用保护性拷贝表面上互相冲突,但实际上,一方面,程序中要避免创建冗余的对象,以减少资源占用;另一方面,在必须创建对象时,那就去创建,以保证程序的安全性和健壮性。程序要兼顾性能和安全。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:37:07- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |