Consider static factpry methods instead of construction

四个优点两个缺点

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

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.

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

A fourth  advantage of static factory methods is that they reduce the vervosity of creating parameterized type instances.

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

A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

注意 static factory method 和 factory pattern 是不同的意思

其中第四点

Foo<Map<Key, Value>> foo = new Foo<Map<Key, Value>>(); vs Foo<Map<Key, Value>> foo = new Foo<Map<Key, Value>>();

不利的地方在于,用了 static fatory 构造函数必须是 private 而继承机制的subclass要求父类是super或者protected, 或者说是在鼓励我们用 composition?

Consider a builder when faced with many constructor parameters当构造的参数很多的时候,又是可以选择性的构造,可以使用builder pattern
public class Dring {private final String name;private final int price;private final int fat;private final int suger;private final int sodium;public static class Builder {//内置的一个static Builder class  让其使用的时候必须是 new Dring.Builder().xxxxxprivate final String name;//这个是必须填写的参数private final int price;private  int fat=0;//
           private  int suger=0;//可选择模式,默认为零private  int sodium=0;public Builder(String name,int price){this.name=name;this.price=price;}public Builder fat (int fat){this.fat=fat;return this;}public Builder suger (int suger){this.suger=suger;return this;}public Builder sodium (int sodium){this.sodium=sodium;return this;}public Dring build (){return new Dring(this);}}private Dring (Builder builder){//不是独立函数 因为都在里面所以可以不用get来使用this.name=builder.name;this.price=builder.price;this.suger=builder.suger;this.fat=builder.fat;this.sodium=builder.sodium;}public String getName() {return name;}public int getPrice() {return price;}public int getFat() {return fat;}public int getSuger() {return suger;}public int getSodium() {return sodium;}}//测试
public class Test2 {public static void main(String[] args) throws Exception {// TODO Auto-generated method stubDring dring = new Dring.Builder("hongniu", 6).fat(50).suger(20).build();System.out.println(dring.getName()+"\n"+dring.getPrice()+"\n"+dring.getSodium()+"\n"+dring.getSuger()+"\n"+dring.getFat());}}
/*
输出
hongniu
6
0
20
50
*/

注意Effecttive Java 和 我自己学的模式设计中的 builder 还是不一样的。注意细看!

Enforce the singleton property with a private constructor an enum type

即是单例模式,设计模式内容看。

Enforce noninstantiability with a private constructor

当需要设计一个静态方法和静态field类的时候,考虑使其无法实例化。

public class StaticM {private  StaticM(){//private之后就无法继承 throw new AssertionError();}public static void  say(){System.out.print("Hello");}
}public class Test2 {public static void main(String[] args) throws Exception {StaticM.say();}}

Avoid creating unnecessary objects

String s = new String ("s") 与String s = "s" 的区别在于,前者无论如何都直接再创建一个对象,后者 如果创建的对象“s”已经之前被创建过了,那么不用new来创建变量,而是创建一个并非是“引用”的“自动”变量。这个变量拥有它的“值”,并置于堆栈中,因此更加高效。

下面摘录自 http://blog.csdn.net/uber001/article/details/51496887的一段文章

浮点数值不适合用于禁止出现舍入误差的金融计算中。例如System.out.println( 2.0 - 1.1);将打印0.899999999999999,而不是0.9。因为浮点数值采用二进制系统表示,而二进制无法精确表示分数1/10,就像十进制无法精确表示1/3一样。如果需要在数值计算中不含有舍入误差,就应该使用BigDecimal类。

一、 包装类(Wrapper Class)共同的方法

JAVA的包装类
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),有些地方也翻译为外覆类或数据类型类。
包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示

包装类对应表 基本数据类型 包装类 
byte Byte 
boolean Boolean 
short Short
char Character 
int Integer
long Long 
float Float
double Double 
在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一直,只是类名的第一个字母大写即可。

值得说明的是,java是可以直接处理基本类型的,但是在有些情况下我们需要将其作为对象来处理,这时就需要将其转化为包装类了.所有的包装类(Wrapper Class)都有共同的方法,他们是:

(1)带有基本值参数并创建包装类对象的构造函数.如可以利用Integer包装类创建对象,Integer obj=new Integer(145);

(2)带有字符串参数并创建包装类对象的构造函数.如new Integer("-45.36");

(3)可生成对象基本值的typeValue方法,如obj.intValue();

(4)将字符串转换为基本值的 parseType方法,如Integer.parseInt(args[0]);

(5)生成哈稀表代码的hashCode方法,如obj.hasCode();

(6)对同一个类的两个对象进行比较的equals()方法,如obj1.eauqls(obj2);

(7)生成字符串表示法的toString()方法,如obj.toString().

转换关系:

基本类型------>包装器类
Integer obj=new Integer(145);

包装器类------>基本类型
int num=obj.intValue();

字符串------>包装器类
Integer obj=new Integer("-45.36");

包装器类------>字符串包装器类

String str=obj.toString();

字符串------>基本类型
int num=Integer.parseInt("-45.36");

基本类型------>字符串包装器类

String str=String.valueOf(5);

二、JDK1.5的新特性:自动装包/拆包(Autoboxing/unboxing)

  自动装包/拆包大大方便了基本类型数据和它们包装类地使用。

  自动装包:基本类型自动转为包装类.(int >> Integer)

  自动拆包:包装类自动转为基本类型.(Integer >> int)

  在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀,现在自动转换机制
解决了我们的问题。

int a = 3;
Collection c = new ArrayList();
c.add(a);//自动转换成Integer.

Integer b = new Integer(2);
c.add(b + 2);

  这里Integer先自动转换为int进行加法运算,然后int再次转换为Integer.

public class Test2 {public static void main(String[] args) throws Exception {
//         Integer i1 = new Integer(100);
//           Integer i11 = new Integer (100);
//           Integer i2 = new Integer (200);
//           Integer i22 = new Integer (200);
//           System.out.println("Is i1==i11  "+(i1==i11));
//           System.out.println("Is i2==i22  "+(i2==i22));  //上面的例子都是false 因为new 的问题?Integer i1 = 100;Integer i11 = 100;Integer i2 = 200;Integer i22 = 200;System.out.println("Is i1==i11  "+(i1==i11));System.out.println("Is i2==i22  "+(i2==i22));
//输出
//           Is i1==i11  true
//           Is i2==i22  false
// 在java的自动封装 auto-boxing 中  Integer在 -128到127中是自动封装成int的所以第一次的比较实际上是比较数值是否对等
//第二次没有自动封装成200,所以比较的是对象是否相等。因为“==”比较是比较地址还是数值,在封装的时候具有一定迷惑性,所以
//如果要进行数值的比较 ,请用equal方法 即 i1.equal(i11)
           }}

除了自动封装类型,还有封装类型和基本类型的使用不要混淆。

public static void main(String[] args) throws Exception {Long sum = 0L;// long sum=0L;时间相比短了非常非常多,性能影响很可怕!for (int x=0;x<Integer.MAX_VALUE;x++){sum +=1;}System.out.println(sum);}// 如果是使用的Long封装数据类型,对于sum+=1是对象级别操作,十分浪费内存,在里面会有new的出现、
//目前个人理解,封装类型的出现时为了map等collection 对于数据是“对象”级处理的需要、

避免不必要的内存生成,下面一个例子摘录自 Effective JAVA

public class Person {  private final Date birthDate;  // DON'T DO THIS!  public boolean isBabyBoomer(){  // Unnecessary allocation of expensive object;  Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));  gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);  Date boomStart = gmtCal.getTime();  gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);  Date boomEnd = gmtCal.getTime();  return birthDate.compareTo(boomStart) >= 0 &&   birthDate.compareTo(boomEnd) < 0;  }
}//这个是错误的class Person {  private final Date birthDate;  private static final Date BOOM_START;  private static final Date BOOM_END;  static {  Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));  gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);  BOOM_START = gmtCal.getTime();  gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);  BOOM_END = gmtCal.getTime();  }  public boolean isBabyBoomer() {  return birthDate.compareTo(BOOM_START) >= 0 &&  birthDate.compareTo(BOOM_END)   <  0;  }
}//对于这两者有什么区别呢?前者每次调用方法的时候,  每次都要生成时间(1946, Calendar.JANUARY, 1, 0, 0, 0)和(1965, Calendar.JANUARY, 1, 0, 0, 0);
//你会发现,既然每次调用用来判断的时间都没有变化,为什么我们每次使用这个方法要再New 一次,这是对资源的浪费,所以在第二个例子,我们将要比较的两个时间用static记录,这样只有在第一次使用的时候需要new,之后就是复用,节省很多空间。

 

Eliminate obsolete object references

虽然java提供了垃圾回收机制,但是垃圾回收并不是万能的,在一些情况下我们也要仔细的小心一些内存溢出的情况,其中一个就是消除无用的引用,因为java垃圾回收装置并不会判断哪些引用对我们人来讲是有用还是无用,需要我们自行判断,就比如下面这个例子

  1. public Object pop(){
  2. if(size==0) throw new EmptyStackException();
  3. return elements[--size];  //这是堆栈的模拟,假设elements[--8],那么其实还是保留了elements[8]的引用,这是个无用引用,没有人为null是无法自动回收的。
  4. }
  1. public Object pop(){
  2. if(size == 0) throw new EmptyStackException();
  3. Object result = elements[--size];
  4. elements[size] = null; // Eliminate obsolete reference  消除引用
  5. return result;
  6. }

内存泄露的另一个常见来源是缓存。一旦你把对象引用放到缓存中,很容易会忘掉它直到它不再有用后仍然停留在缓存中。(尚且未涉及缓存)

Avoid finalizer

所谓JAVA终结器,就是JAVA自动回收所使用的函数方法 finalize()。

这个终结函数可以说是一无是处,只是提供了,万一我们忘记了手动释放一些重要资源,他能释放,晚点比没有好,但是正常情况下,资源的释放很重要,我们必须用好。意思说,终结器不要用。

1.终结方法的缺点在于不能保证会及时的执行。

2.及时的执行finalize()方法时垃圾回收算法的一个主要功能,这种算法在不同的JVM实现中大相径庭。(不可依赖,因为不同的算法不同的表现)

3.Java语言规范不仅不能保证finalize()方法会被及时的执行,而且根本就不保证他们会执行。

4.还有一点,使用finalize()有一个非常严重的Severe性能损失。

垃圾回收器只有在内存不够的时候才会调用。

最好使用 try finally

转载于:https://www.cnblogs.com/s1127736971/p/7469115.html

Creating and Destroying Objects相关推荐

  1. Chapter2 Creating and Destroying Objects

  2. 【Effective Java】第二章:静态工厂、构建器、强化Singleton属性、私有构造器、

    文章目录 一. 用静态工厂方法代替构造器 优势: 劣势: 实例代码: 二. 遇到多个构造器参数时要考虑使用构建器 ① 重叠构建器 ② JavaBeans模式 ③ Builder模式 三. 用私有构造器 ...

  3. 《Windows核心编程》读书笔记二十五章 未处理异常,向量化异常处理与C++异常

    第二十五章  未处理异常,向量化异常处理与C++异常 本章内容 25.1 UnhandledExceptionFilter函数详解 25.2 即时调试 25.3 电子表格示例程序 25.4 向量化异常 ...

  4. 5天带你读完《Effective Java》(一)

    <Effective Java>是Java开发领域无可争议的经典之作,连Java之父James Gosling都说:"如果说我需要一本Java编程的书,那就是它了".它 ...

  5. Creating a Game with CocosBuilder

    转载地址:http://code.zynga.com/2012/10/creating-a-game-with-cocosbuilder/ This tutorial aims to show how ...

  6. Pthread:POSIX Threads Programming

    POSIX Threads Programming Blaise Barney, Lawrence Livermore National Laboratory 译文点此 Table of Conten ...

  7. angular 学习理解笔记

    原文: https://github.com/eoinkelly/notes/blob/master/angular/book-building-web-apps-w-angular/angular. ...

  8. Effective C# 原则16:垃圾最小化(译)

    Effective C# 原则16:垃圾最小化 Item 16: Minimize Garbage 垃圾回收器对内存管理表现的非常出色,并且它以非常高效的方法移除不再使用的对象.但不管你怎样看它,申请 ...

  9. C# Programming Language学习笔记(三)

    第二章 词法结构 The lexical grammar defines how Unicode characters are combined to form line terminators, w ...

最新文章

  1. 如何使用拦截器获取Controller方法名和注解信息?
  2. 湖南卫视新年巨献敲定 《恋爱兵法》显偶像魅力
  3. windows找不到文件gpedit.msc_此电脑右键管理提示windows找不到文件的解决方法
  4. dj电商-数据库的远程连接
  5. svn拉取文件合并_svn - SVN - 大象笔记
  6. Linux core文件生成及设置 查看core文件由哪个程序生成的
  7. php物料编码生成器,物料编码生成器下载|
  8. c语言锁存器写入1,总线接口作两种用途,为何就要用到锁存器
  9. 小程序云开发(二) 上传图片到云服务器、上传图片并展示
  10. Ubuntu11.04下安装QQ2011
  11. CapAnalysis Pcap分析工具
  12. 【NLP】自然语言处理的中间序列建模
  13. 题目 1460: 2n皇后问题
  14. 《一本书读懂24种互联网思维》用户思维1
  15. jacob解决freemaker下载的word文档手机无法打开问题
  16. 关于使用WMI获取杀毒软件信息
  17. jester数据集 下载_使用Jester测试您的测试
  18. 织梦dedecms手机上,自动跳转到/m目录mobile手机版h5页面
  19. 计算机工程在铁路上能做什么,值得推荐的4个“交通”专业,毕业后直接进入铁路系统,工作不愁...
  20. [Python] ERROR:argument of type ‘datetime.date‘ is not iterable

热门文章

  1. php mysql 类型_php mysql bigint 类型
  2. mysql触发器中访问mssql数据表_[数据库]一个利用触发器(trigger)实现数据库表的审计功能(audit)的例子--针对ms sql实现...
  3. 实验楼Python项目
  4. 4、根据前序和中序,重建二叉树
  5. 如何真正学好数据科学?
  6. Android 关于java.util.NoSuchElementException错误
  7. Container 系列 - NAS - Introduction
  8. javascript/jquery给动态加载的元素添加click事件
  9. u3d打包成exe以及调试
  10. python 中类与对象