`

创建和销毁对象

 
阅读更多

     想写一下关于Java高效开发的一些方法总结,作为自己技术提升的一种必要反省。同时为我们在每一次编写程序代码时,更多的考虑一下我们这样写代码是不是更高效,更简单的一种方法。

     今天第一次写,后续会陆续发出关于Java高效开发的一些总结文章。希望有任何想法的Java同行们一同共勉,同时编写博客也是为了训练自己的表达的能力,作为技术成长的一个见证。好了,废话不多说。

     对象的创建和销毁

     对象的创建,我们都知道,采用new这种方式。同时提供默认的无参构造方法就可以。对于一些必要的参数我们想在new对象的时候就初始化,可以复写或者叫重载多个参数的构造参数new对象。这种情况我们在编写大部分的程序的时候都遇到过,但是也有一些特殊情况,比如我们的对象确实有很多数据域构成,这时候在采用这种构造方法重载的情况,感觉就有点繁重而且不好理解。对于new对象的时候 就有些累赘,所以我们应该考虑这种情况下 我们怎么才能更好的new我们的对象。

    第一种方法,考虑用静态工厂的方式替代构造器

    这种方式我们在编写所谓的单例模式类的时候,通过会这样做。就是提供默认的私有构造器,同时提供一个返回该类实例的一个public  static 的静态方法,防止new出多个该class的对象来,以实现我们的单例类。

还有在Java JDK中经常看到这种代码Integer.valueOf(xxxx),这种类型转换的方法,这也属于静态工厂方法,

    采用这种方法的好处,我们也说一下:

    a,它们有一个更好理解的名称,正如上面所描述的那样,如果有多个构造参数的话,你根本不知道它们的具体含义,如果说你们在不看文档注释的前提下;还有一个问题是,连我自己也会忽略的一个问题是,对于多个数据域的class我们未必会给每个数据域都加上一个可以理解的注释,这是每个程序员都有或存在的问题(ps:如果你没有的话,请自行略过该段)。所以,当一个类需要多个带有相同签名的构造器时,考虑用静态工厂方法来替代它吧,并选择一个别人能见名知意的方法名

    b,不必在每次调用他们的时候都创建一个新对象,这样可以省掉很大的一些new对象的开销,我们可以预先创建好对象,然后把它缓存起来,等到使用时直接拿来用即可。避免创建不必要的重复对象。其实这里能更好回答这个问题的就是singlton模式了。

    c,它们可以返回原返回类型的任何子类型的对象,这样在返回对象时,又有了更大的灵活性。这一点可以参照,JDK 5中的Collection Framwork的不可修改集合,同步集合等,他们都是通过静态工厂方法在一个不可实例化的类中导出的。

这里我们提及一下服务提供者框架(Service Provider Framework),它有三个重要的组件:服务接口(Service Interface),这是提供者实现的;提供者注册API(Provider Registration API),这是系统用来注册实现,让客户端访问他们的;服务访问API(Service Access API),是客户端用来获取服务的实例的。服务访问API是”灵活的静态工厂“,它构成了服务提供者框架的基础。还有一个是服务提供者接口(Service Provider Interface)它是可选的组件,它负责创建其服务实现的实例。举个经常使用的例子,对于JDBC来说,Connection就是的它的服务接口,DriverManager.registerDriver是提供者注册API,DriverManager.getConnection是服务访问API,Driver是服务提供者接口。

      d,在创建参数化类型实例的时候,它们使代码变得更加简洁,这个可以参照Collection Framework中的源码实现。

     静态工厂方法的缺点有两点:

     一是类如果不含有公有的或者受保护的构造器,就不能被子类化,

     二是他们与其他的静态方法实际上没有任何区别,这的意思是说,在jdk中没有明显标识出来。对于有多个方法的类来说,找到一个实例化类的静态工厂方法也是非常困难的。

    第二种方法,遇到多个构造参数时,考虑采用构建器(builder)

它同样和静态工厂方法一样,适合有多个构造参数时使用的另一种构造对象的方法。

package cn.effectivejava.createobject.bulider;

/**
 * 采用构建器模式创建对象实例
 * @author qd
 *
 */
public class NutritionFacts {
	
	private final int servingSize;//required
	private final int servings;//required
	private final int calories;//optional
	private final int fat;//optional
	private final int sodium;//optional
	private final int carbohydrate;//optional
	
	public static class Builder{
		//required parameters
		private final int servingSize;
		private final int servings;
		
		//optional parameters
		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){
			this.calories= val;
			return this;
		}
		
		public Builder fat(int val){
			this.fat=fat;
			return this;
		}
		
		public Builder carbohydrate(int val){
			this.carbohydrate = val;
			return this;
		}
		
		public Builder sodium(int val){
			this.sodium =val;
			return this;
		}
		
		public NutritionFacts build(){
			return new NutritionFacts(this);
		}
	}
	private NutritionFacts(Builder builder){
		this.servingSize=builder.servingSize;
		this.servings = builder.servings;
		this.calories=builder.calories;
		this.fat = builder.fat;
		this.sodium =builder.sodium;
		this.carbohydrate =builder.carbohydrate;
	}
}

 我们可以采用如下方式,构建对象:

NutritionFacts cocalCola = new NutritionFacts.Builder(240, 8)
							.calories(100).sodium(35).carbohydrate(27).build();
		System.out.println(cocalCola.calories);

 这里我们可以和设计模式中的builder模式参照对比来学习和理解该模式的应用方式和场景。

与构造器相比,builder的微略优势在于,builder可以有多个可变参数。构造器就像方法一样,只能有一个可变参数。因为builder用每一个方法来设置参数,你想要多少个可变参数,就可以有多少个可变参数。

   它还可以结合泛型的方式构建各种对象,也可以采用有限制的通配符类型来约束构建器的类型参数。

   简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择。特别是当大多数参数都可选的时候,相比其他方式,使用Builder模式的客户端代码将更易于阅读和编写。

分享到:
评论

相关推荐

    Qt6 QML Book/动态QML/创建和销毁对象示例源码

    在本文中,我们将深入探讨Qt6中的QML技术,特别是关注如何动态地创建和销毁对象。QML是Qt框架提供的一种强大的声明式编程语言,它允许我们构建具有丰富用户界面的应用程序。Qt6版本带来了许多改进和新特性,使得QML...

    C#创建、销毁对象和继承

    “对象和内存”涉及到C#的垃圾回收机制。当对象不再被引用时,系统会自动回收其占用的内存。然而,对于处理非托管资源(如文件句柄或数据库连接)的对象,应使用`using`语句或实现`IDisposable`接口来确保资源的正确...

    JAVA创建和销毁对象的方法

    在Java编程中,创建和销毁对象是至关重要的操作,它们直接影响到程序的性能和内存管理。本文将深入探讨Java中创建对象的几种方法以及对象的销毁。 首先,我们来看看创建对象的基本方式——构造器。构造器是每个类都...

    监听器:监听三个对象的创建和销毁方法

    本次工程的目标是学习监听器,掌握监听三个对象的创建和销毁方法。 三个对象:rquest,session,ServletContext 实现的接口:ServletRequestListener,HttpSessionListener,ServletContextListener 工程的大致步骤...

    【原】unity 不销毁对象的处理

    "不销毁对象的处理"这个话题涉及到如何在游戏运行过程中保持某些对象的状态,而不是在不再需要时销毁它们,然后在需要时重新创建。这通常用于实现持久化数据、避免频繁的实例化和销毁开销,或者维护一些全局的游戏...

    基于Java的对象池管理系统.zip

    本项目是一个基于Java的对象池管理系统,旨在通过对象池技术减少频繁创建和销毁对象所带来的开销,从而提高系统性能和资源利用率。对象池技术允许在需要时从池中获取已存在的对象,而不是每次都创建新对象,使用完毕...

    游戏对象池例子(兼容智能指针、工厂类)

    游戏开发中的对象池技术是一种优化资源管理的策略,它通过预先创建并缓存一组对象,以避免频繁地创建和销毁对象带来的性能开销。在这个"游戏对象池例子(兼容智能指针、工厂类)"中,我们将探讨如何利用C++实现这种...

    对象池 射击游戏 子弹的反复生成

    如果频繁地创建和销毁这些子弹,会消耗大量的内存和CPU资源,因为创建和销毁对象的过程是相对昂贵的。对象池的出现就是为了解决这个问题。 对象池的基本思想是预先创建一组对象,并将它们存储在一个集合中,当需要...

    deePool高效的JavaScript对象池

    JavaScript是一种动态类型的编程语言,广泛应用于Web开发,其在处理大量临时对象时,可能会因为频繁创建和销毁对象而导致性能下降。为了解决这个问题,开发者们引入了“对象池”概念, DeePool 就是一个实现这一概念...

    高效的,固定大小的对象池

    对象池的基本思想是通过减少频繁地创建和销毁对象来提升性能。当程序需要对象时,它会从池中获取一个已经初始化好的对象,而不是调用构造函数创建新的。使用完毕后,对象不是被销毁,而是返回到池中,供后续使用。...

    用Dictionary写的对象池

    这种方式可以减少频繁创建和销毁对象带来的性能开销,尤其是在处理大量短生命周期对象的场景下。本文将深入探讨如何使用Dictionary来实现一个简单的对象池,并分析其工作原理、优缺点以及适用场景。 首先,我们来...

    C#自定义对象池

    这样可以避免因频繁创建和销毁对象带来的性能损失。 在C#中实现自定义对象池,首先需要定义一个类来存储和管理这些对象。这个类通常包含一个队列或字典来保存对象,以及一些方法如获取对象、归还对象等。以下是一个...

    对象池简单Demo(资源包)

    1. **减少GC压力**:避免频繁创建和销毁对象,减少垃圾收集器的工作量,提高游戏运行效率。 2. **提高性能**:通过复用对象,减少实例化和销毁的时间开销。 3. **资源管理**:更好地控制对象的生命周期,避免因瞬间...

    万能对象池【C#实现】

    在编程领域,对象池是一种设计模式,用于管理对象的创建和销毁,以提高程序性能,尤其是在频繁创建和销毁对象的场景下。本文将详细讲解如何使用C#语言实现一个通用的对象池,以及它背后的原理和优势。 首先,理解...

    Java对象池技术的原理及其实现

    1. **减少创建与销毁开销**:频繁地创建和销毁对象会导致大量的CPU时间消耗在内存分配和垃圾回收上,而对象池能够有效减少这种开销。 2. **节省内存资源**:对象池限制了对象的最大数量,避免了大量临时对象占用内存...

    C++对象池源码示例

    对象池是一种优化资源管理的技术,特别是在频繁创建和销毁对象的场景下。本篇将深入探讨对象池的概念、工作原理以及如何在C++中实现对象池。 对象池的基本思想是预先创建并维护一组对象,而不是每当需要时就动态地...

    性能优化_对象池

    "对象池"是一种常见的性能优化策略,它针对的是频繁创建和销毁对象所导致的性能损失。本文将深入探讨对象池的概念、工作原理以及在实际应用中的优势和注意事项。 对象池的基本思想是预先创建并维护一组对象,而不是...

Global site tag (gtag.js) - Google Analytics