Effective Java:Ch2_创建销毁对象:Item1_考虑用工厂方法替代构造函数
本章的主题是创建和销毁对象:何时创建、怎样创建;何时应该避免创建、如何避免创建;如何确保对象适时被销毁;如何管理对象销毁前的清理动作。
一个类如果要允许客户获得其实例,常用方法是提供一个public的构造函数。还有另外一个方法,也应该在每个程序员的工具集中占有一席之地:类可以提供一个public的静态工厂方法,这个方法返回类的实例。【例】下面是Boolean类(基本类型boolean对应的包装类)代码里的一个简单示例,该方法将一个boolean简单类型转换为一个Boolean对象引用。
public static Boolean valueOf(boolean b){ return b ? Boolean.TRUE : Boolean.FALSE; }注意这里讲的静态工厂方法与设计模式中的工厂方法模式是不一样的,它在设计模式中没有直接等价物。
类可以提供给它的客户静态工厂方法,用来替代构造方法,或作为构造方法的补充。用静态工厂方法来替代public构造方法既有优点也有缺点。
优点一:静态工厂方法不同于构造函数,他们有名称。如果构造函数的参数不能确切地描述正被返回对象,那么具有合适名称的静态工厂方法就更易用,对应的客户端代码页更加易于阅读。【例】例如,构造方法BigInteger(int, int, Random)返回一个可能为素数的BigInteger,而用一个名为BigInteger.probablePrime()的静态工厂方法就更好。(JDK1.4最终增加了这个方法。)
public class BigInteger extends Number implements Comparable<BigInteger> { public static BigInteger probablePrime(int bitLength, Random rnd) { if (bitLength < 2) throw new ArithmeticException("bitLength < 2"); // The cutoff of 95 was chosen empirically for best performance return (bitLength < SMALL_PRIME_THRESHOLD ? smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) : largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd)); } public BigInteger(int bitLength, int certainty, Random rnd) { BigInteger prime; if (bitLength < 2) throw new ArithmeticException("bitLength < 2"); // The cutoff of 95 was chosen empirically for best performance prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd) : largePrime(bitLength, certainty, rnd)); signum = 1; mag = prime.mag; } }对于指定的方法签名,一个类只能有一个对应的构造函数。程序员通常这样来避开这个限制:可以提供两个构造函数,他们的参数列表仅仅是参数类型的顺序不同。这实在是一个坏主意。API的用户将不会记得这些构造函数哪个是哪个,常会无意地调用错误的构造函数。其他人读到使用这些构造函数的代码时,将不会知道这些代码是做什么的,除非参考类文档。
由于静态工厂方法有名称,所以没有上述限制。假如一个类需要方法签名相同的多个构造函数,就用静态工厂方法来替代构造函数,并仔细地选择方法名称以便突出它们之间的区别。
优点二:静态工厂方法不同于构造函数,无需每次被调用时都创建一个新对象。这使得非可变类(Item15)可以使用预先创建的实例,或者在创建实例时缓存起来,之后分发给客户,从而避免创建不必要的重复对象。Boolean.valueOf(boolean)方法演示了这种技术:它从不创建对象。这种技术类似于Flyweight模式。如果客户端经常请求创建相同的对象,那这种技术能极大的提高性能,尤其是当创建对象开销很大时。
静态工厂方法可以再反复调用时返回同一个对象,这使得类可以严格控制在哪个时刻有哪些实例存在。这种类又被称为实例受控的类(instance-controlled)。编写实例受控的类有这么几个理由:第一,实例受控允许一个类确保是单例的(Item3),或者是不可实例化的(Item4);同时,实例受控允许非可变类(Item15)确保不会存在两个相等的实例,即当且仅当a==b时才有a.equals(b),如果一个类做出了这种保证,则它的客户端可以用==操作符来地带equals(Object)方法,这可能会提高性能。枚举类型(Item30)就保证了这一点。
优点三:静态工厂方法不同于构造函数,它能返回任意子类型的对象。这让你在选择返回对象的类型时有了很大的灵活性。
这种灵活性的一个应用是,API可以返回一个对象,而无需使对象的类public。用这种方式隐藏实现类能够产生一个非常紧凑的API。这种技术适用于基于接口的框架(interface based frameworks, Item18),在这种框架中,接口成为静态工厂方法的自然返回类型。由于接口不能有静态方法,所以按照惯例,接口Type的静态工厂方法被放在一个名为Types的不可实例化类(noninstantiable
class, Item4)中。
【例】例如,Java集合框架中有32个集合接口的便利实现,提供不可修改的集合、同步集合等等。几乎所有的实现都通过一个不可实例化类(java.util.Collections)中的静态工厂方法导出,返回对象的类都是非public的。——Collections.unmodifiableMap(Map)方法的返回类型是UnmodifiableMap,是个private类!
public class Collections { public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) { return new UnmodifiableMap<K,V>(m); } private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable { } }如果把上述便利实现都作为public类导出,那集合框架API会臃肿很多。而且这并不仅仅是API数量的减少,还有conceptual weight的减轻。用户知道返回的对象都是由API通过接口精确定义了的,所以无需为实现类阅读额外的类文档。此外,使用静态工厂方法后,要求客户端通过接口来引用返回对象,而不是通过实现类来引用返回对象,这通常是一个好习惯。
public静态工厂方法返回的对象类型不仅是可以非public,而且还能根据参数的不同,而返回不同的类型。只要是所声明的返回类型的任何子类型,都是允许的。为了提高软件可维护性和性能,返回类型还可以随着版本的不同而不同。
【例】JDK1.5版本引入的java.util.EnumSet类没有public构造函数,只有静态工厂方法。根据底层枚举类型的大小,这些工厂方法可以返回两种实现:如果拥有64个或更少的元素(大多数枚举类型都是这样),静态工厂方法返回一个RegularEnumSet实例,用单个long来支持;如果枚举类型拥有65个或更多的元素,静态工厂方法则返回JumboEnumSet实例,用long数组来支持。
这两种实现类的存在对客户端是不可见的。如果RegularEnumSet对于小的枚举类型提供性能优势,那么就能在以后的版本中删掉,并不产生副作用。同样,如果可以提高性能,以后版本可以增加EnumSet的第三或第四个实现。客户端不知道也不关心静态工厂返回的对象的类型,客户端只关心它是EnumSet的某个子类。
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> implements Cloneable, java.io.Serializable { public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); if (universe.length <= 64) return new RegularEnumSet<E>(elementType, universe); else return new JumboEnumSet<E>(elementType, universe); } } class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> { } class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> { }
在编写静态工厂方法时,其返回的对象所属的类甚至可以不存在。静态工厂方法的这种灵活性形成了服务提供者框架(service provider frameworks)的基础,例如Java数据库连接API(JDBC)。所谓服务提供者框架是这样一个系统:在这个系统中多个服务提供者实现一个服务,系统让这些实现对客户端可用,使他们与实现解耦。
服务提供者框架中有三个重要组件:服务接口(service interface),它负责提供实现;提供者注册API(provider registration API),系统用它来注册实现,让客户端访问实现;服务访问API(service access API),客户端用它来获取服务的一个实例,它一般允许客户端指定选择提供者的条件,但并不强制要求。如果不指定,则API返回一个默认实现的实例。服务访问API是“灵活的静态工厂”,形成了服务提供者框架的基础。
服务提供者框架还有第四个可选组件:服务提供者接口(service provider interface),提供者实现它用来创建其服务实现的实例。如果没有服务提供者接口,实现则是通过类名来注册,并通过反射实例化(Item53)。【例】以JDBC为例,Connection就是服务接口(service interface);DriverManager.registerDriver是提供者注册API(provider
registration API);DriverManager.getConnection是服务访问API(service access API);Driver是服务提供者接口(service provider interface)。
服务提供者框架有多种变体。例如服务访问API可以通过适配器模式,返回比提供者要求的更加丰富的服务接口。【例】下面是一个简单示例,有一个服务提供者接口,和一个默认提供者:
//Service provider framework sketch //--1)Service interface public interface Service{ //service-specific methods go here } //--4)Service provider interface public interface Provider{ Service newService(); } //Noninstantiable class for service registration and access public class Services{ private Services(){} //pervents instantiation //maps service names to services private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>(); public static final String DEFAULT_PROVIDER_NAME = "<def>"; //--2)provider registration API public static void registerDefaultProvider(Provider p){ registerProvider(DEFAULT_PROVIDER_NAME, p); } public static void registerProvider(String name, Provider p){ providers.put(name, p); } //--3)service access API:静态工厂方法 public static Service newInstance(){ return newInstance(DEFAULT_PROVIDER_NAME); } public static Service newInstance(String name){ Provider p = providers.get(name); if(p == null){ throw new IllegalArgumentException(); } return p.newService(); } }
优点四:静态工厂方法创建参数化类型实例时更加简洁。如果你调用参数化类的构造函数,那么很不幸,你必须要指定类型参数,即便上下文中已明确了类型参数。这通常要求你连续两次提供类型参数:
Map<String, List<String>> m = new HashMap<String, List<String>>();
随着类型参数长度和复杂性的不断增长,这种冗长的规范很快变得痛苦起来。然而,使用静态工厂的话,编译器能够替你计算出类型参数。这就是类型推导(type inference)。【例】例如,假设HashMap提供了如下静态工厂:
public static <K, V> HashMap<K, V> newInstance(){ return new HashMap<K, V>(); }
然后你就可以讲上文冗长的声明替换为如下这种简洁的形式:
Map<String, List<String>> m = HashMap.newInstance();也许有一天Java可以再构造函数调用和方法调用时进行这种类型推导,不过截至JDK1.6还不能做到。
遗憾的是,JDK1.6版本的标准集合实现(如HashMap)中并没有工厂方法,不过你可以再自己的工具类中加入这些方法。更重要的是,你可以再自己的参数类类中提供这种静态工厂。
缺点一:只提供静态工厂方法的主要缺点是,没有public或protected构造函数的类不能被子类化。public静态工厂返回的非public类也同样如此。例如,你不能子类化集合框架中便利实现类。这样也好,它鼓励程序员使用复合,而不是继承(Item16)。
缺点二:静态工厂方法不容易与其他静态方法相区分。它们并不像构造函数在API文档中那样突出,所以如果类提供静态工厂方法而不是构造函数,要找出如何实例化该类就比较困难了。也许某一天Javadoc工具会注意到静态工厂方法。现阶段,你可以通过在类或接口注释中标注静态工厂,并遵守通用的命名习惯,来减少这一缺陷。静态工厂方法的一些常用命名如下:
valueOf——不严格地讲,该方法返回一个与其方法参数具有相同值的实例。这种静态工厂实际上是类型转换方法。
of——valueOf的简洁形式,EnumSet(Item32)使之流行起来。
getInstance——返回方法参数所描述的一个实例,不过不一定与方法参数具有相同值。在单例模式中,getInstance没有参数,返回唯一实例。
newInstance——与getInstance类似,不过newInstance确保返回的每个实例都是不同的。
getType——与getInstance类似,只不过当工厂方法在另外一个不同的类中的时候使用。Type表示工厂方法返回对象的类型。
newType——与newInstance类似,只不过当工厂方法在另外一个不同的类中的时候使用。Type表示工厂方法返回对象的类型。
总之,静态工厂方法和public构造方法各有用处,我们需要理解他们各自的长处。通常静态工厂更可取,所以第一反应应该是考虑使用静态工厂,而不是public构造函数。
相关推荐
内容概要:本文详细介绍了Harnefors观测器在永磁同步电机(PMSM)无感控制中的应用,特别是其在Matlab 2020b环境下的仿真模型。Harnefors观测器以其简洁的十行核心代码实现了对电机角度的精确估算,仅需调整单一参数lambda即可应对各种工况。文中展示了该观测器在初始角度误差极大情况下的优异收敛性能,以及在带载启动和多种速度指令下的稳定性。此外,模型中引入的有效磁链概念使得同一观测器能够兼容表贴式和内嵌式电机,进一步提升了其实用性和灵活性。仿真结果显示,该观测器不仅能在极端条件下迅速收敛,还能在不同电机参数下保持稳定的性能表现。 适合人群:从事电机控制系统设计与开发的技术人员,尤其是关注无感FOC技术和观测器优化的研究人员。 使用场景及目标:①用于研究和开发高性能无感FOC系统;②评估和改进现有电机控制系统的观测器设计;③为初学者提供一个简洁而高效的观测器实现案例,帮助理解和掌握相关技术。 其他说明:文章提供了详细的代码片段和实验数据,便于读者进行复现和进一步探索。同时,强调了模型的扩展性和实用性,特别是在不同类型的永磁同步电机中的应用。
内容概要:本文详细介绍了使用COMSOL软件中的相场法进行水力压裂模拟的技术细节。首先探讨了单一裂缝的扩展机制,包括相场参数的选择如界面厚度参数(epsilon)、断裂能(Gc),以及各向异性分散设置的影响。接着逐步深入到多个裂缝簇的竞争扩展,特别是两簇和三簇裂缝之间的应力阴影效应及其对裂缝形态的影响。文中还讨论了水力裂缝与天然裂缝相交时的特殊处理方法,如接触条件设定、摩擦系数调整等。此外,文章强调了网格划分、时间步长设置等数值模拟的关键技巧,并展示了如何利用相场变量的动态可视化来直观地观察裂缝的生长过程。 适合人群:从事石油工程、地质力学、计算力学等领域研究的专业人士和技术人员。 使用场景及目标:适用于希望深入了解水力压裂过程中裂缝形成机理的研究人员,以及希望通过数值模拟优化压裂作业的设计工程师。主要目标是掌握相场法的基本原理及其在COMSOL平台上的具体实现方式,从而更好地理解和预测实际工程中的裂缝行为。 其他说明:文章不仅提供了详细的MATLAB代码片段用于指导具体的建模步骤,还分享了许多实用的经验和技巧,帮助读者规避常见的数值发散等问题。同时,通过对不同工况的对比分析,揭示了相场法在处理复杂裂缝网络方面的优势。
管道清污机器人sw16可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
该资源为keras-3.3.2.tar.gz,欢迎下载使用哦!
C语言课程设计的一些经典项目以及源码.zip
水果采摘机器人sw22_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
爬百度文库ppt(1)
新能源电机sw22可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
内容概要:本文详细介绍了利用CNN-LSTM混合模型进行锂离子电池健康状态(SOH)估计的方法。首先,通过对NASA公开数据集的分析,提取了三个关键特征:放电电压最低点时间、平均放电电压和平均放电温度。接着,构建了一个由卷积神经网络(CNN)和长短时记忆网络(LSTM)组成的混合模型,用于捕捉电池数据的局部特征和时序依赖。模型经过精心调参和优化,在NASA B0005和B0006电池数据集上取得了优异的表现,RMSE低于1.5%,MAPE控制在1.5%左右。此外,文中提供了完整的Python代码实现,包括数据预处理、模型搭建、训练和结果可视化的具体步骤。 适合人群:从事电池管理系统的研发人员、机器学习工程师以及对深度学习应用于电池健康管理感兴趣的科研工作者。 使用场景及目标:适用于需要精确评估锂离子电池健康状态的应用场合,如电动汽车、储能系统等领域。主要目标是提高电池使用寿命预测的准确性,从而优化电池维护计划并延长设备使用寿命。 其他说明:文中强调了特征选择的重要性,并指出合理的特征工程可以显著提升模型性能。同时提醒使用者在实际应用中结合电池管理系统的实时数据进行在线校准,以获得更好的预测效果。
内容概要:本文详细探讨了在三相不平衡电压条件下,T型NPC三电平并网逆变器的控制策略及其具体实现方法。首先介绍了正负序分离技术,利用复数旋转因子和双二阶广义积分器(DSOGI)进行坐标变换,将三相电压分解为正序和负序分量。接着讨论了中点电位平衡问题,采用零序电压注入的方法并通过PI调节器来稳定中点电位。随后阐述了空间矢量脉宽调制(SVPWM)的具体实现步骤,包括矢量选择逻辑和作用时间计算。此外,文章还涉及电流环参数的设计,提供了基于电网阻抗特性的PI参数调整方法。最后展示了仿真实验结果,验证了所提出控制策略的有效性和优越性能。 适合人群:电力电子工程师、从事逆变器研究的技术人员以及相关领域的研究生。 使用场景及目标:适用于需要解决三相不平衡电压问题的并网逆变器控制系统设计,旨在提高系统的稳定性、可靠性和效率。 其他说明:文中提供的代码片段和仿真模型有助于读者更好地理解和应用这些控制策略。建议读者结合实际硬件条件进行适当调整,并参考相关文献深入学习。
GEE教学-个快快版-共28讲.rar
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
1、文件说明: Centos8操作系统thai-scalable-tlwgtypewriter-fonts-0.6.5-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf thai-scalable-tlwgtypewriter-fonts-0.6.5-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
内容概要:本文详细介绍了如何利用Simulink搭建永磁同步电机(PMSM)的谐波注入补偿模型,重点在于抑制5次和7次电流谐波。文中解释了谐波产生的原因及其危害,如电机发热、振动增加等问题。随后逐步讲解了如何使用Simulink中的各个模块(如PMSM模块、Universal Bridge、PI Controller、FFT模块等),并通过协调这些模块实现了谐波的有效抑制。此外,还探讨了谐波提取、谐振控制器设计、补偿信号发生器的设计细节,以及如何应对转速突变工况下的挑战。通过实验验证,该模型能够显著降低5次和7次谐波含量,提高电机性能。 适合人群:从事电机控制系统设计的研究人员和技术工程师,尤其是对永磁同步电机谐波抑制感兴趣的读者。 使用场景及目标:适用于需要深入理解和掌握永磁同步电机谐波抑制技术的研发人员,旨在帮助他们构建高效的谐波抑制系统,提升电机运行效率和稳定性。 其他说明:文中提供了详细的Matlab/Simulink代码片段和配置建议,有助于读者快速上手实践。同时,强调了实际应用中的注意事项,如选择合适的求解器、设置合理的参数等,确保仿真的准确性。
内容概要:本文详细介绍了基于T型三电平逆变器的虚拟同步机(VSG)控制技术,涵盖VSG的核心算法、中点电位平衡策略以及LCL滤波器的双闭环控制设计。首先探讨了VSG控制的基本原理,包括虚拟惯量和阻尼特性的模拟,以及有功-频率和无功-电压下垂控制的具体实现。针对T型三电平拓扑特有的中点电位漂移问题,提出了多种平衡控制方法。对于LCL滤波器,讨论了其参数设计和双闭环控制策略,特别是电流环PI参数的选择和避免谐振的方法。文中还提供了多个实用的经验公式和调试技巧,并引用了相关领域的权威文献作为理论支持。 适合人群:从事电力电子、新能源并网系统研究和开发的技术人员,尤其是有一定电力电子基础的研发人员。 使用场景及目标:适用于需要深入了解和掌握VSG控制技术和LCL滤波器设计的研究人员和技术开发者。主要目标是帮助读者理解和实现T型三电平逆变器的VSG控制,提高系统的稳定性和性能。 其他说明:文中不仅提供了详细的理论解释,还有具体的代码实现和调试建议,便于读者进行实际操作和验证。同时强调了调试过程中需要注意的安全事项和常见问题的解决方案。
内容概要:美国大学生数学建模竞赛(MCM/ICM)由美国数学及其应用联合会主办,旨在提高学生运用数学知识和计算机技术解决实际问题的能力,培养团队合作精神和创新思维。竞赛始于1985年,至今已有近40年历史,是全球最具影响力的数学建模竞赛之一。竞赛分为MCM和ICM两部分,涵盖多个领域,参赛队伍需在4天内完成题目的分析、建模、求解和论文撰写。竞赛面向全球在校大学生,设有多个奖项,获奖对学生的升学和就业有积极影响。参赛队伍应提前学习数学建模知识,掌握常用软件工具,如MATLAB、Python等,同时加强团队协作和时间管理能力。; 适合人群:全球范围内的在校大学生,特别是对数学建模感兴趣的学生。; 使用场景及目标:①提高学生运用数学知识和计算机技术解决实际问题的能力;②培养团队合作精神和创新思维;③为升学和就业积累宝贵经验。; 阅读建议:参赛队伍应提前做好充分准备,学习相关数学建模知识,熟悉常用软件工具,加强团队协作和时间管理能力,以应对竞赛的挑战。
电子电力仿真教程 ,15篇,5000字,从入门到精通,案例为主。
汽车横梁拧螺丝设备sw22可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
内容概要:本文详细介绍了基于三电平逆变器的有源电力滤波器(APF)的设计及Matlab/Simulink仿真验证。首先阐述了三电平逆变器的基本原理,包括其拓扑结构和优势。接着讨论了APF的核心功能,即通过检测电网中的谐波电流并生成补偿电流来抵消谐波。文中给出了具体的谐波检测算法和补偿电流生成控制策略,如瞬时无功功率理论和谐波检测算法、SVPWM控制算法等。最后,通过搭建Matlab/Simulink仿真模型,验证了所设计方案的有效性,展示了APF投入前后电网电流谐波含量的显著变化,证明了三电平逆变器在APF中的优越性能。 适合人群:电气工程专业学生、从事电力电子研究的技术人员、对电力系统谐波治理感兴趣的科研工作者。 使用场景及目标:适用于高校教学、企业研发部门和技术培训课程。主要目标是帮助读者掌握三电平逆变器的工作原理、APF的设计思路及其实现方法,同时提供详细的仿真指导,以便于实际工程项目中的应用。 其他说明:文章不仅提供了理论分析,还包括了大量的代码示例和具体的操作步骤,有助于读者更好地理解和实践。此外,文中还指出了仿真过程中常见的几个问题及解决方案,进一步提高了实用性和可靠性。
内容概要:本文详细介绍了信号时延估计这一重要信号处理任务,涵盖了从经典方法到创新方法的发展历程。首先解释了时延估计的基础概念及其广泛应用背景,如声纳定位、语音增强、地震勘探和雷达测距等领域。接着分别探讨了几种经典时延估计方法,包括基于相关分析的方法、高阶累积量方法、特征结构分析方法、代价函数优化方法以及自适应处理方法,指出了各自的优势和局限性。重点介绍了基于频率滑动广义互相关(FSGCC)的创新方法,该方法通过在频域内滑动窗口,计算广义互相关函数,提高了时延估计的精度和鲁棒性,尤其适用于非平稳信号和强噪声环境。文中还提供了详细的MATLAB代码示例,展示了如何生成带有时延的信号、实现各种时延估计方法,并比较了不同方法在不同条件下的性能。 适合人群:从事信号处理研究和技术开发的专业人士,尤其是对时延估计感兴趣的科研人员和工程师。 使用场景及目标:①理解和掌握多种时延估计方法的工作原理;②学习如何在MATLAB中实现这些方法;③探索频率滑动广义互相关方法在实际工程中的应用潜力。 其他说明:文章不仅提供了理论讲解,还包括了大量的代码实例,帮助读者更好地理解和实践。此外,还讨论了一些实际应用中的注意事项,如计算复杂度和实时性要求等。