疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java基础提高篇对象的创建


 

   

  我一直使用构造器的方式生成或者初始化对象。最近发现一些对象在项目中并没有实际作用,有时我只是需要它的一些功能,为此新建一个对象是不是比较消耗资源,影响程序的性能呢。今天看到一些资料,对这个问题作出了一个回答。

  说明:

  首先肯定的是,我们有时候并不需要一个类的全部功能,或许我们需要的只是其中的一两个方法,没必要为此新建一个类。静态方法解决了这个问题。静态方法应该成为每个面向对象设计程序者必修课程。首先我们学习静态方法创建对象。

  使用静态工厂的方式产生对象的好处有这样几个好处:“一:静态方法都有名字,使得你更明白自己在干什么”;“二:使用静态方法不必在每次创建对象,节省了内存”;“三:更灵活,可以返回原返回类型的任何子类型的对象”“四:代码看起来更简洁”;当然它也有缺点的,其中一个主要的缺点是,如果使用静态方法产生对象,那么似乎就可以不包含公有或者受保护的构造器,这样的话子类想继承的话就是不可能的事了。这个可以通过复合避开继承来解决这个问题。

  下面将介绍几个比较著名的静态构造器的例子。

  第一个例子:多参数类

  考虑这个一个需求,我需要建一个类。这个类是用来描述商品的产品说明的,那么这个类就会有很多的参数,并且在每个对象对这个类中的参数需求都是不同的。如果使用重叠构造器,你需要写很多的构造器,最多需要2的n次方个构造器。当然我不会这样写,我会使用javaBeans模式生成get、set方式。这种方式有缺点,老实说以我现在还看不到这样写的危害,似乎是在多线程中是不安全的。这里还是推荐给大家一个更安全更完善的构造方法:

  使用builder模式来生成对象。大概的想法是这样的:在这种多参数类的内部构建一个builder的内部类,使用内部类接收传参,最后才是更新外部类的参数。这样做的好处可以是事前检测数据的合法性,对于不合法的数据可以事先处理掉,保证了数据的安全性。这里给出一个例子(要编写以及使用这样的类,你需要知道内部类的语法),

 

  public class BuiltTest {

  private String name1, name2, name3, name4, name5, name6, name7;

  /*

  * 内部类builder

  */

  public static class Built {

  private String name1, name2, name3, name4, name5, name6, name7;

  public Built setname1(String name1) {

  this.name1 = name1;

  return this;

  }

  public Built setname2(String name2) {

  this.name2 = name2;

  return this;

  }

  public Built setname3(String name3) {

  this.name3 = name3;

  return this;

  }

  public Built setname4(String name4) {

  this.name4 = name4;

  return this;

  }

  public Built setname5(String name5) {

  this.name5 = name5;

  return this;

  }

  public Built setname6(String name6) {

  this.name6 = name6;

  return this;

  }

  public Built setname7(String name7) {

  this.name7 = name7;

  return this;

  }

  public BuiltTest built() {

  return new BuiltTest(this);

  }

  }

  //构造方法

  private BuiltTest(Built built) {

  this.name1 = built.name1;

  this.name2 = built.name2;

  this.name3 = built.name3;

  this.name4 = built.name4;

  this.name5 = built.name5;

  this.name6 = built.name6;

  this.name7 = built.name7;

  }

  //重写toSting方法

  @Override

  public String toString() {

  String str="My name is "+name1+","+name2+","+name3+","+name4+","+name5+","+name6+","+name7;

  return str;

  }

  }

  调用的代码:

  //创建一个BuiltTest对象

  BuiltTest a=new BuiltTest.Built().setname1("xiaohua").setname2("小小").setname3("安徽").built();

  这种builder方法建立起来的对象,经过测试在参数大于等于4时,性能是更优的。考虑到程序的扩展性,最好一开始就使用builder的构造器。

  第二个例子:强化Singleton属性

  在一些程序中,为了数据安全,我们仅需要一个对象,这时我们需要Singleton模式。Singleton有三种写法,第一种定义一个Singleton的常量,第二种方法使用工厂的方式返回一个Singleton的对象,第三种方式是返回一个枚举类型的对象。在多线程安全性能上第三种方式是最安全的。

  //第一种方式,产生一个final的对象,私有化构造方法

  public class Elvis {

  public static final Elvis INSTANC_ELVIS = new Elvis();

  private Elvis() {

  }

  }

  //第二章方法,又构造器产生一个Singleton的对象

  public class Elvis {

  private static final Elvis INSTANC_ELVIS = new Elvis();

  private Elvis() {

  }

  public Elvis getElvis(){

  return INSTANC_ELVIS;

  }

  }

  //第三种方法,编写一个enum 类

  public enum Elvis {

  INSTANC_ELVIS;

  }