Effective Java之避免创建不必要的对象
Effective Java中有很多值得注意的技巧,今天我刚开始看这本书,看到这一章的时候,我发现自己以前并没有理解什么是不必要的对象,所以拿出来跟大家探讨一下,避免以后犯不必要的错误!
首先书中对不可变的对象(immutable)做了简单解释:不可变对象都是可以重用的。因为String是不可变对象,所以这样创建String是没有必要的:
```java
String str = new String("abc");
```
`'abc'`本身就是一个String实例了,再用实例去包裹他,就属于浪费资源了。这样创建的话,`'abc'`就可以实现重用了:
```java
String str = "abc";
```
如果本身不是不可变对象,JDK中很多类也提供了重用的功能。了解和使用它们,可以避免创建不必要对象。
例如`Long`、`Integer`等,都提供了`valueOf()`的静态方法。`Calendar`等也提供了`getInstance()`方法。
上面都不是重点,很多人都已经了解他们了。下面探讨一个很有意思的问题,看这段代码:
```java
Long sum = 0L;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
```
JDK1.5支持自动装箱和拆箱,我们不用进行类型转换了。但作者说这里有一个疏忽,导致了计算时间的大大提升,我很是没看出来。其实这个问题还是大标题所讲的:创建了不必要的对象。
`sum`是一个`Long`类型的对象,在他本身相加的时候,他会再创建一个`Long`对象,因为这些对象的不同,决定他们不能重用,而就这样,我们创建了`Integer.MAX_VALUE`个`Long`对象。想想挺恐怖的,虽然创建一个对象的开销很小,但也不能这样玩儿。
解决之道就是把`Long sum`换成`long sum`,使用了基本类型,他们是在栈中,也没有创建对象一说,性能提升不止一倍。
在我的计算机上,`Long`计算花费30秒, `long`花费了3.1秒左右。
避免创建不必要的对象,注意自动装箱带来的影响,这一点在以后要提高警惕!
当然,不能因噎废食,章中最后的解说,个人感觉也非常精彩: 当然,我们不要认为创建对象的代价非常昂贵,因为小对象的构造器只做很少量的显式工作,他的创建和回收动作是非常廉价的。通过创建附加的对象,提升程序的清晰性、间接性和功能性,这通常是件好事。
反之,使用对象池来创建对象并不是一种好的做法,除非池中的对象是非常重量级的。
Effective Java之避免创建不必要的对象的更多相关文章
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- [Effective Java]第二章 创建和销毁对象
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- Effective Java读书笔记--创建和销毁对象
1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build() ...
- Effective java笔记(二),所有对象的通用方法
Object类的所有非final方法(equals.hashCode.toString.clone.finalize)都要遵守通用约定(general contract),否则其它依赖于这些约定的类( ...
- Java中类的创建及类与对象的关系
//import java.util.Scanner; //创建一个类 class Person{ //属性和方法的定义不是必须的 //属性 String name ; int age ; //方法 ...
- 什么是不可变对象(immutable object)?Java 中怎么 创建一个不可变对象?
不可变对象指对象一旦被创建,状态就不能再改变.任何修改都会创建一个新的对象,如 String.Integer 及其它包装类. 详情参见答案,一步一步指导你在 Java中创建一个不可变的类.
- Effective Java学习笔记--创建和销毁对象
创建和销毁对象 一.静态工厂方法代替构造器 静态工厂方法的优缺点 优点: 1.可以自定义名称(可以将功能表述的更加清晰) 2.不必每次调用都创建新的对象(同一对象重复使用) 3.返回的类型可以是原返回 ...
- Java中如何创建一个新的对象的/Creating Objects/
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't ...
- 《Effective Java》第3章 对于所有对象都通用的方法
第8条:覆盖equals时请遵守通用约定 覆盖equals方法看起来似乎很简单,但是有许多覆盖方式会导致错误,并且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每 ...
随机推荐
- google project tango 学习笔记
google io 2015上 project tango 的演示视频
- ASP.NET MVC 5 入门教程 (2) 控制器Controller
文章来源: Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc-5-get-started-controller.html 上一节:ASP.NET MVC ...
- Sublime Text 之 Package Control 镜像
本文同步自我的个人博客:http://www.52cik.com/2015/11/24/Package-Control.html 这阵子经常有朋友跟我说 Sublime Text 下的 Package ...
- 你所不知道的Python奇技淫巧
有时候你会看到很Cool的Python代码,你惊讶于它的简洁,它的优雅,你不由自主地赞叹:竟然还能这样写.其实,这些优雅的代码都要归功于Python的特性,只要你能掌握这些Pythonic的技巧,你一 ...
- El Capitan 中 SIP 介绍
http://havee.me/mac/2015-10/system-integrity-protection-on-el-capitan.html 这两天大家纷纷将 OS X 系统升级到了 El C ...
- NHibernate扫盲
NHibernate中Get和Load的区别 (1) get()采用立即加载方式,而load()采用延迟加载; get()方法执行的时候,会立即向数据库发出查询语句, 而load()方法返回的是一个代 ...
- [wikioi 2845]排序的代价(置换群)
有一列数,要对其进行排序(升序).排序只能通过交换来实现.每次交换,可以选择这列数中的任意二个,交换他们的位置,并且交换的代价为二个数的和.排序的总代价是排序过程中所有交换代价之和.先要求计算,对于任 ...
- 深入理解C#泛型
前面两篇文章介绍了C#泛型的基本知识和特性,下面我们看看泛型是怎么工作的,了解一下泛型内部机制. 泛型内部机制 泛型拥有类型参数,通过类型参数可以提供"参数化"的类型,事实上,泛型 ...
- WeisEditor 3.2.1B 使用说明 [源码下载]
WeisEditor 使用说明 1. 首先打开(Weiseditor)编辑器文件夹下js/config.js 如果此时你的项目是一个虚拟目录项目 WeisConfig.isVirtualPath = ...
- Sencha Touch 手机移动开发框架 HTML5 项目压缩方案;
Sencha Touch框架生成基本项目目录结构 Index.html/ App.js App.json /touch[sdk]/ /Sencha-touch.js /src Resources/ A ...