【Java基础】创建和销毁对象
Num1:考虑用静态工厂方法代替构造器
对于类而言,常见的方法是提供一个公有的构造器,但其实还有一种方法叫做静态工厂方法(static factory method),它只是一个返回类的实例静态方法。
目前比较流行的规范是把静态工厂方法命名为valueOf或者getInstance。
valueOf:该方法返回的实例与它的参数具有同样的值,例如:
Integer a=Integer.valueOf(100); //返回取值为100的Integer对象
从上面代码可以看出,valueOf()方法能执行类型转换操作,在本例中,把int类型的基本数据转换为Integer对象。
getInstance:返回的实例与参数匹配,例如:
Calendar cal=Calendar.getInstance(Locale.CHINA); //返回符合中国标准的日历
优势:
- 静态工厂方法与构造器不同的第一大优势在于,他们有名称,更有可读性。
- 静态工厂方法与构造器不同的第二大优势在于,不必每次调用它们的时候都创建一个新对象。
- 静态工厂方法与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象。
- 静态工厂方法与构造器不同的第四大优势在于,在创建参数化实例的时候,它们使代码变得更加简洁。
缺点:
- 类如果不含公有的或者受保护的构造器,就不能被子类化。
- 它们与其他的静态方法实际上没有任何区别。
Num2:遇到多个构造器参数时要考虑用构造器
一般有以下三种构造器的方式
- 重叠构造器模式
- JavaBeans模式
- Builder模式
重叠构造器模式
public class NutritionFacts {
private final int servingSize; // (mL) required
private final int servings; // (per container) required
private final int calories; // optional
private final int fat; // (g) optional
private final int sodium; // (mg) optional
private final int carbohydrate; // (g) optional
public NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings, int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
this(servingSize, servings, calories, fat, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium) {
this(servingSize, servings, calories, fat, sodium, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
public static void main(String[] args) {
NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);
}
}
JavaBeans模式
在这种模式下,调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数。如下:
public class NutritionFacts {
// Parameters initialized to default values (if any)
private int servingSize = -1; // Required; no default value
private int servings = -1; // " " " "
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() {
}
// Setters
public void setServingSize(int val) {
servingSize = val;
}
public void setServings(int val) {
servings = val;
}
public void setCalories(int val) {
calories = val;
}
public void setFat(int val) {
fat = val;
}
public void setSodium(int val) {
sodium = val;
}
public void setCarbohydrate(int val) {
carbohydrate = val;
}
public static void main(String[] args) {
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
}
}
Builder模式
不直接生成想要的对象,而是让调用者利用所有必要的参数调用构造器,得到一个builder对象,然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数,最后客户端调用无参的build方法来生成一个不可变的对象。
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
public static void main(String[] args) {
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
}
}
小结####
与构造器相比,builder模式的优势在于,builder可以有多个可变的参数,构造器就像方法一样,只能有一个可变参数。总之,如果类的构造器或静态工厂中具有多个参数,设计这种类的时候,builder模式就是一种不错的选择。
Num3:用私有构造器或者枚举类型强化Singleton属性
Singleton简单的说就是仅仅被实例化一次的类。实现Singleton有三种方式。
Field方式
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void leaveTheBuilding() {
System.out.println("Whoa baby, I'm outta here!");
}
// This code would normally appear outside the class!
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
Method方式
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public static Elvis getInstance() {
return INSTANCE;
}
public void leaveTheBuilding() {
System.out.println("Whoa baby, I'm outta here!");
}
// This code would normally appear outside the class!
public static void main(String[] args) {
Elvis elvis = Elvis.getInstance();
elvis.leaveTheBuilding();
}
}
特别要说明下,如果要使得类支持可序列化,仅仅加上implements Serializable是不够的,需要在方法里加上这么一个方法。
private Object readResolve() {
// Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE;
}
枚举类方式
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() {
System.out.println("Whoa baby, I'm outta here!");
}
// This code would normally appear outside the class!
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
Num4:消除过期的对象引用
所谓过期引用:是指永远也不会再被解除的引用。在支持垃圾回收的语言中,内存泄露是很隐蔽的,如果一个对象引用被这个对象无意识地保留起来,那么,垃圾回收机制不仅不会处理这个对象,而且也不会处理被这个对象所引用的所有其他对象,从而对性能造成潜在的重大影响。
那么该如何修复呢,很简单:一旦对象引用已经过期了,只需要清空这些引用即可。
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
一般而言,只要类是自己管理内存,程序员就应该警惕内存泄露问题。
内存泄露的另一个常见问题是缓存,所以一般可以弱引用weak reference代表缓存,当缓存过期后,它们会自动被删除,记住缓存项的生命周期是外部引用而不是值引用的。
内存泄露的第三个常见来源是监听器和其他回调。如果你实现了一个API,客户端在这个API中注册回调,却没有显式地取消注册,那么除非采取某些动作,否则就会积聚,确保回调立即被当作垃圾回收的最佳方法是只保存它们的弱引用。
【Java基础】创建和销毁对象的更多相关文章
- 《Effective Java》—— 创建与销毁对象
本篇主要总结的是<Effecticve Java>中关于创建和销毁对象的内容. 比如: 何时以及如何创建对象 何时以及如何避免创建对象 如何确保及时销毁 如何管理对象销毁前的清理动作 考虑 ...
- 和我一起学Effective Java之创建和销毁对象
前言 主要学习创建和销毁对象: 1.何时以及如何创建对象 2.何时以及如何避免创建对象 3.如何确保它们能够适时地销毁 4.如何管理对象销毁之前必须进行的清理动作 正文 一.用静态工厂方法代替构造器 ...
- Effective Java - [2. 创建与销毁对象]
让对象的创建与销毁在掌控中. Item 1: 使用静态工厂方法而非使用构造函数 public static Boolean valueOf(boolean b) { return b ? Boolea ...
- Java进阶 创建和销毁对象
最近准备写点Javase的东西,希望可以帮助大家写出更好的代码. 1.给不可实例化的类提供私有构造器 比如:每个项目中都有很多工具类,提供了很多static类型的方法供大家使用,谁也不希望看到下面的代 ...
- 【读书笔记】《Effective Java》——创建和销毁对象
Item 1. 考虑用静态工厂方法替代构造器 获得一个类的实例时我们都会采取一个共有的构造器.Foo x = new Foo(): 同时我们应该掌握另一种方法就是静态工厂方法(static facto ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- effective java读书小记(一)创建和销毁对象
序言 <effective java>可谓是java学习者心中的一本绝对不能不拜读的好书,她对于目标读者(有一点编程基础和开发经验)的人来说,由浅入深,言简意赅.每一章节都分为若干的条目, ...
- [Effective Java]第二章 创建和销毁对象
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 《Effect Java》学习笔记1———创建和销毁对象
第二章 创建和销毁对象 1.考虑用静态工厂方法代替构造器 四大优势: i. 有名称 ii. 不必在每次调用它们的时候都创建一个新的对象: iii. 可以返回原返回类型的任何子类型的对象: JDBC ...
- Effective Java(1)-创建和销毁对象
Effective Java(1)-创建和销毁对象
随机推荐
- Linux环境下解压超过4GB的zip文件
今天在Linux服务器中解压一个zip的压缩包,提示如下错误信息: [root@appsrv01 ZIP_BCSA_COURSES]# unzip BCSA_MEDIAS_BAK_20161118.z ...
- SQL Saturday活动再起
SQL Saturday活动再起 时间:2015年05月09日(星期六) 地点:上海徐汇区港汇2座10楼(10.073) 我们相约港汇2座10楼(10.073),SQL PASS上海分会的SQLSat ...
- SQL入门经典(四)之创建和修改数据表
本章主要讲如何使用脚本创建数据库:如何使用脚本创建表:如何删除对象和修改对象. CREATE 语句:CREATE <object type> <onject name> 创建数 ...
- javascript中this指针探讨
javascript是一门类java语言有很多跟java相类似的特点,但也仅是类似而已,真正使用中还是有很大的差别.this指针常常让很多初学者抓狂,本人也曾为此困惑不解,查找过很多资料,今天在这里总 ...
- 【网站国际化必备】Asp.Net MVC 集成Paypal(贝宝)快速结账 支付接口 ,附源码demo
开篇先给大家讲段历史故事,博主是湖北襄阳人.襄阳物华天宝,人杰地灵,曾用名襄樊.在2800多年的历史文化中出现了一代名相诸葛亮(卧龙),三国名士庞统(凤雏),魏晋隐士司马徽(水镜先生),唐代大诗人孟浩 ...
- http学习笔记(一)
写在前面: 第一次想写系列文章,学习了一些web知识后,发现自己还有很大的不足,但又不知道该学习些什么来完善自己的知识体系,偶然在网上看到了一篇介绍http的文章,觉得对自己有一些帮助,于是想要开始学 ...
- Windows 10 下安装 npm 后全局 node_modules 和 npm-cache 文件夹的设置
npm 指 Node Package Manager,是 Node.js 中一个流行的包管理和分发工具.Node.js 在某个版本的 Windows 安装包开始已经加入了 npm,现在可以进入 htt ...
- C#高级一
1.单例模式:又叫单件模式,属于创建型模式分类.实际上讲,一个对象只允许创建一个实例,并且提供了一个全局的访问点. (静态方法生命周期长,消亡时间短,GC不回收) ================= ...
- MyBatis入门学习(一)
一.MyBatis入门简要介绍(百科) MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyB ...
- Java基础之网络编程
网络编程:1.网络编程概述 (1)网络模型 OSI参考模型 TCP/IP参考模型 (2)网络通讯要素 IP地址 端口号 传输协议 (3)网络通讯前提: **找到对方IP **数据要发送到指定端口.为了 ...