`
withoutme_hw
  • 浏览: 10053 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

1.Creating and Destroying Objects——Effective Java 2nd Ed学习笔记

阅读更多

 

1.One advantage of static factory methods is that, unlike constructors, they have names.

 

有时候,一个类有几个不同的构造函数,各个构造函数只能靠参数来区分,编写程序和阅读程序的时候构造子的意义都不明确。而是用静态工厂方法可以明确的知道该构造子的含义,比如BigInteger(int, int, Random),这个构造子返回的可能是一个素数,但是在代码上并没有体现出来,使用BigInteger.probablePrime()静态工厂方法的意义就明确得多了。

 

2.A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.

 

有时候并不需要每次都创建一个新的对象实例,就可以使用静态工厂方法,避免了创建对象的性能损失。比如Boolean.valueOf(boolean),使用该方法不会重新创建一个Boolean对象,它的代码如下,很明显,这比每次都创建一个新对象在性能上要好得多。This technique is similar to the Flyweight pattern [Gamma95, p. 195].

 

public static Boolean valueOf(boolean b) {

 

return b ? Boolean.TRUE : Boolean.FALSE;

 

}

 

而且有时,静态工厂方法还可以用来保证没有两个相等的对象同时存在,所以在这种情况下可以直接使用a==b判断两个对象是否相等,比使用equals方法效率高。

 

3.A third advantage of static factory methods is that, unlike constructors,they can return an object of any subtype of their return type.

 

a) One application of this flexibility is that an API can return objects without making their classes public.

For example, the Java Collections Framework has thirty-two convenience implementations of its collection interfaces, providing unmodifiable collections,synchronized collections, and the like.Nearly all of these implementations are exported via static factory methods in one noninstantiable class (java.util.Collections).The classes of the returned objects are all nonpublic.这样使用者完全不需要了解那些类就可以使用它们,而且这也使得使用者可以 针对接口编程。

b) Not only can the class of an object returned by a public static factory method be nonpublic, but the class can vary from invocation to invocation depending on the values of the parameters to the static factory.java.util.EnumSet没有公共的构造子,只有静态工厂方法,该方法实际上返回EnumSet的两种不同的实现(这一点使用者完全不需要了解):如果EnumSet大 小小于64,就返回RegularEnumSet实例(当然它继承自EnumSet),这个EnumSet实际上至用了一个long来存储这个EnumSet。如果EnumSet大小大于等于64,则返回JumboEnumSet实例,它使用一个long[]来存储。这样做的好处很明显:大多数情况下返回的RegularEnumSet效率比JumboEnumSet高很多。

 

c) The class of the object returned by a static factory method need not even exist at the time the class containing the method is written.这是service provider frameworks的基础。

 

比如说Java Database Connectivity API 就是一个 service provider frameworks,在编写JDBC的时候,各个厂商所提供的JDBC驱动根本就不存在,但是JDBC API却能返回这些厂商的JDBC对象。service provider frameworks有3个基本的组件:1.服务接口(service interface),服务的提供者必须实现该接口,在JDBC中是Driver接口,2. 服务提供者注册(provider registration)API,JDBC中即DriverManager.registerDriver()3.服务访问(service access)API,JDBC中即DriverManager.getConnection

 

d) A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized typeinstances.(这一点已经没有优势了,因为JDK1.7对此做了简化)

 

Map<String, List<String>> m = new HashMap<String, List<String>>();

 

==> Map<String, List<String>> m = HashMap.newInstance();

 

4.The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.

 

5.A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.而且,在Javadoc中,静态工厂方法不如构造子醒目,对使用者造成一定困难。

 

对于静态工厂方法的区分度不够可以通过命名规范来改进:valueOf, of, getInstance, newInstance, getType, newType

 

Item 2: Consider a builder when faced with many constructorparameters

 

场景:编写一个商品的营养成分类,有超过20种营养元素,而实际中一个商品包含的营养元素也就几种。这样一个类的构造子将会相当大,并且其中无意义的项非常多,每一个参数仅仅靠它的位置来确定它的意义,这样意义不明确,阅读起来不易懂,编写困难,容易出现错误(比如几个参数的位置弄错),这样的错误通常隐晦而难以发现(让程序及早知道错误并提示这个错误是重要的!)。比如:

 

NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 0, 0, 35, 27, 0, 0, 0);//很难知道哪个数字对应哪个营养

 

一种解决方案是使用JavaBean,如下:NutritionFacts cocaCola = new NutritionFacts();NutritionFacts cocaCola = new NutritionFacts();

cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);

至少这样做参数的意义明确得多,但是这样做有严重的缺点:a JavaBean may be in an inconsistent state partway through its construction,一个构造过程被分成若干步,如果其中某一步出错,程序将会使用一个不确定的对象,这会导致很多隐晦而难以发觉的错误。还有一个缺点是:the JavaBeans pattern precludes the possibility of making a class immutable。

使用Builder模式的解决方案代码如下: // Builder Pattern

		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;
			}
		}

 在使用时,这样写:NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

The Builder pattern simulates named optional parameters as found in Ada and Python.
The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters

Item 3: Enforce the singleton property with a private constructor or an enum type
单例模式的实现方式:
1. // Singleton with public final field
public class Elvis
{
	public static final Elvis INSTANCE = new Elvis();
	private Elvis() { ... }
	public void leaveTheBuilding() { ... }
}

这样做可以明确的知道这个对象是单例的,但是Joshua Bloch说:a privileged client can invoke the private constructor reflectively(Item 53) with the aid of the AccessibleObject.setAccessible method. If you need to defend against this attack, modify the constructor to make it throw an exception if it’s asked to create a second instanc  2. 

分享到:
评论

相关推荐

    CSharp - Module 9_Creating and Destroying Objects

    在IT领域,尤其是在编程语言的学习与应用中,C#(C Sharp)作为一款由微软开发的面向对象的、类型安全的、垃圾回收的程序设计语言,其在创建和销毁对象方面的处理方式是开发者必须掌握的核心技能之一。本文将基于...

    Effective Java 3rd edition(Effective Java第三版英文原版)附第二版

    2 Creating and Destroying Objects Item 1: Consider static factory methods instead of constructors Item 2: Consider a builder when faced with many constructor parameters Item 3: Enforce the singleton ...

    Programming with MS VB.NET.pdf

    Contents Introduction Course Materials..................Creating and Destroying Objects...........................................................................16 Demonstration: Creating Classes.....

    VB.Net Programming.pdf

    Creating and Destroying Objects.......................................................................16 Demonstration: Creating Classes..................................................................

    MSDN Traning - VB.NET (VBL).pdf

    Creating and Destroying Objects.................................................................16 Demonstration: Creating Classes.................................................................23 ...

    Programming with Microsoft Visual Basic.NET_Delivery Guide.pdf

    Creating and Destroying Objects.................................................................16 Demonstration: Creating Classes.................................................................23 ...

    Unit 3 Science and nature作业题及答案解析6份3精选.docx

    3. "Instead, he thinks research efforts should concentrate ________ creating new tissues and organs that can be used to cure diseases like cancer." ——此处应填"on",意为研究应该集中在创造新的组织和...

    微软.NET程序员高级培训教程系列资料.C#(下)【英文版】

    7. **创建与销毁对象(Creating and Destroying Objects)**:"CSharp_Module 9_Creating and Destroying Objects.pdf"将涵盖对象的生命周期,包括构造函数、析构函数和垃圾回收机制,以及何时和如何适当地分配和释放...

    C++语言程序设计第三版试卷

    - Destroying..1 - Destroying..0 程序首先创建了一个Samp类型的动态数组,然后逐个设置元素值并输出,最后释放内存。析构函数在每个对象被删除时执行,显示其内部存储的i的值。 10. Vector类是一个动态数组的...

    C++语言程序设计__期末考试试题及答案.pdf

    Destroying..1 Destroying..0 该资源摘要信息提供了一个完整的C++语言程序设计期末考试试题,涵盖了面向对象编程、函数重载、递归调用、拷贝构造函数、继承、多态性等C++编程概念,为C++语言学习者和考试者提供了一...

    JAVA小实验雷电(打飞机)

    1 You will find more useful informations in the following lessons: “Java GUI”, “Java Graphics”, “Applet and Multimedia”. The lesson ‘multithreading ’ maybe is useful to some advanced ...

    C# 微软基础教程PPT

    7. **Creating and Destroying Objects**:学习如何创建和销毁对象,理解对象生命周期和垃圾回收机制。 8. **Inheritance in C#**:子类继承父类的属性和方法,实现代码重用和扩展。 9. **Aggregation, Namespaces...

    Unreal Engine 4.X By Example

    - **Trigger Volumes and Destroying Actors**: Detecting when actors should be removed. - **Debugging Our Blueprints**: Identifying and fixing issues. - **Masking Our Destruction with Particles**: ...

    TongWeb7应用开发手册.pdf

    TongWeb是东方通科技推出的一款高性能的企业级Java应用服务器,它支持最新的Servlet规范和其他Web技术,如JSP和JSF,以帮助开发者构建复杂的Web应用程序。 ### Servlet Servlet是一种Java编程接口,用于扩展服务器...

    KafkaOffsetMonitor监控工具2017年1月发布的版本

    Instead, closing and destroying the client and re-creating it. Sleeping on error before re-creating client and continuing to process Deal with thread-safety issues on shared memory between threads ...

    Msdn Training - Microsoft Visual Studio Net (With Source)

    模块9:《C# - Module 9_Creating and Destroying Objects.pdf》 本模块讲解了对象的生命周期,包括构造函数和析构函数的使用,以及垃圾回收机制。学习者将了解如何在适当的时间创建和释放对象,以优化内存管理。 ...

    推选文档Java小程序PPT.ppt

    Java小程序的生命周期是一个重要的概念,理解它对于编写和调试Java Applet至关重要。Applet的生命周期由四个主要状态组成:初始化(Initialization)、加载(Loading)、启动(Starting)、绘画(Painting)、停止...

    ns2.34的蚁群算法补丁

    The changelog below should be helpful to you in getting Antnet into ns2.34 without destroying your additions. Instructions copy the files provided into NS2.34 directory as is. Run: ./configure make...

    Java版电子宠物游戏代码

    Java版电子宠物游戏代码,package Petgame; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Petgame extends MIDlet { private static Petgame instance; private ...

    django-failedfirsttestrunner:重新排序测试套件,以便在随后的测试运行中首先运行失败的测试

    django-failedfirsttestrunner ...Destroying test database for alias ' default ' ... Creating test database for alias ' default ' ... :woman_dancing::woman_dancing:.......................

Global site tag (gtag.js) - Google Analytics