Java方法中的参数太多,第4部分:重载

期望将过多的参数传递给Java方法的问题之一是,该方法的客户端很难确定它们是否以适当的顺序传递了适当的值。 在以前的文章中,我描述了如何使用自定义类型 , 参数对象和构建器来解决此问题。 解决此问题的另一种方法(也是本文的主题)是提供相同方法的重载版本 ,以使客户可以使用最适合其需求的方法。 就像我之前关于过多方法参数的文章一样,我将在本篇文章的结尾简要讨论这种方法的优缺点。

Java支持方法重载 ,即能够通过其方法签名区分同一方法的不同版本。 请注意,两种方法之间唯一的区别是不同的返回类型通常不足以实现重载。

可能出于多种原因应用方法重载。 重载方法的一个目标可能是在不同类型上支持相同的功能(尤其是如果无法使用泛型来允许该方法支持不同类型,或者如果在泛型可用之前编写了这些方法)。 考虑到此意图的方法重载示例包括String.valueOf(boolean) , String.valueOf(char) , String.valueOf(double) , String.valueOf(long) , String.valueOf(Object)和其他一些版本String.valueOf重载在其他一些类型上。

选择重载方法的另一个原因是,客户端可以调用方法的适当版本以仅提供必要的参数。 例如,可以这样做,以消除客户端为不适用或可选的参数传递一个或多个null的需要。 为实现此目的而编写的重载方法的示例包括Date类的构造函数,例如Date(int,int,int) , Date(int,int,int,int,int)和Date(int,int,int,int,int,int) ,int,int) 。

这种具有许多重载版本构造函数(每个构造函数都接受不同数量的参数)的方法称为伸缩构造函数,并已被某些人称为反模式 。 实际上,这种伸缩式构造方法的缺点是Josh Bloch专注于Effective Java第二版第2项中的Builder模式的驱动因素之一。 顺便说一下, Date类还提供了一些重载的构造函数,它们也旨在实现上述目标,例如,允许从String构造Date 。

提供多个重载方法和构造函数以接受一组减少的必需或最低适用参数的想法可以应用于我们自己的类。 下一个代码清单为原始方法提供了太多的参数,然后显示了该方法的一些潜在的重载版本,这些版本接受减少的参数集。 为了便于讨论,我们假设未在覆盖的方法签名之一中提供的任何参数是可选的,或不适用于该特定方法调用。 代码注释说明了每种方法如何做出某些假设以减少其参数数量。

方法过多且版本重载的参数示例

/*** Generates and provides an instance of the Person class. This method* expects all characteristics of the populated Person instance and so any* optional or not applicable characteristics must be passed in as null.* * @param lastName* @param firstName* @param middleName* @param salutation* @param suffix* @param streetAddress* @param city* @param state* @param isFemale* @param isEmployed* @param isHomeOwner* @return A Person object.*/public Person createPerson(final String lastName,final String firstName,final String middleName,final String salutation,final String suffix,final String streetAddress,final String city,final String state,final boolean isFemale,final boolean isEmployed,final boolean isHomeOwner){// implementation goes here...}/*** Generate and provide an instance of the Person class that has only a first* and last name and address information. This method does not make any* assumptions about other characteristics of the instantiated Person, but* simply leaves those attributes undefined.* * @param lastName* @param firstName* @param streetAddress* @param city* @param state* @return Instance of Person class with no middle name and without specified*    gender, employment status, or home ownership status.*/public Person createPerson(final String lastName,final String firstName,final String streetAddress,final String city,final String state){// implementation goes here...}/*** Generate and provide instance of Person class with no middle name and* with specified home ownership status. All instances of Person returned* from this method are assumed to be Female and to be Employed, but have no* address information.* * @param lastName* @param firstName* @param homeOwnerStatus* @return Instance of Person with provided first name, provided last name,*    and provided home ownership status, and assumed to be an employed*    female.*/public Person createPerson(final String lastName,final String firstName,final boolean homeOwnerStatus){// implementation goes here...}

重载方法的Javadoc描述介绍了它们的不同方法。 第一种方法期望提供Person实例的所有特征,而对于不适用的参数,则需要提供null(例如,如果一个人没有中间名,或者该中间名对于在此中的使用不重要)案件)。 第二个重载版本不希望提供所有参数,并假定它不希望的参数在返回的Person实例中仍未定义。

第三种重载方法版本大多是针对其特性未提供明确参数的假设。 例如,假设实例化的Person既是女性又是雇员。 第三种方法无法实例化男性或失业人员。 这说明了通过简单的方法重载处理太多参数的缺点(仅根据参数的数量和类型重载具有相同名称的方法)。

我在这篇文章中没有显示我自己的任何构造函数,但是同样的问题和方法也适用于上述非构造函数方法。 同样,重载的构造函数与重载的非构造函数方法具有相同的优点和缺点。

优势与优势

Java中的方法重载似乎很容易理解,并且在包括C / C ++和C#在内的多种语言中很常见。 当参数是可选的时,方法重载特别有效。 例如,在我的示例中,重载方法消除了传递中间名的期望,比重载方法假设特定实例是受雇女性要有效得多。 如果中间名,性别和就业状况的特征确实是可选的,那么根本不假设任何一个值都比假设它们的特定值更好。

成本与劣势

明智的方法重载可能很有用,但方法重载必须谨慎使用。 “ 学习Java语言 ” 课程的“ 类和对象”课程的“ 定义方法”部分警告:“应谨慎使用重载方法,因为它们会使代码的可读性大大降低。”

即使是我简单的三个示例,也显示了如何使重载很快变得难以阅读。 在我的示例中,此代码的阅读者或用户要么需要仔细阅读Javadoc并相信它是最新且准确的,要么需要深入研究实现以查看该方法的每个重载版本的作用。 在IDE中,尤其是如果同一方法有许多重载版本,则很难确定哪种方法适用于给定的情况。

我的示例表明,必须使用注释来解释重载方法所做的假设。 如前所述,如果开发人员不费心地编写它们,它们可能会过时,不准确甚至不可用。 能够以不同的方式命名方法显然更好,这样方法的名称可以提供有关其假设的线索,而不是仅依赖于Javadoc。 以这种方式使用命名方法将是以后的主题,但是根据定义为方法使用不同的名称将使其不再重载。

我的示例显示了使用带有相同类型的多个参数的重载(同名)方法的特定限制。 第三个示例接受一个boolean ,但是只有Javadoc和该参数的名称可以告诉我它适用于房屋所有权,而不适用于性别或就业状况。 我无法提供类似的重载方法来使用相同的名称信息和一个boolean ,该boolean表示不同的内容(例如性别或工作状态),因为该方法与该boolean表示房屋所有权状态的方法具有相同的签名。 再次可以通过使用不同命名的方法来补救,这些方法指出了它们适用于哪种布尔条件。

解决此最后提到的限制的另一种方法是使用自定义类型和/或参数对象,并提供接受这些自定义类型的不同组合的重载方法的各种版本。 这在下一个代码清单中与自定义类型一起显示,该代码显示了对于这三个案例,当三个案例中的每个案例不需要共享同一类型时,如何通过单个第三个参数来重载接受两个名称字符串的方法。

自定义类型启用改进的方法/构造函数重载

public Person createPerson(final String lastName,final String firstName,final HomeownerStatus homeOwnership){// implementation goes here...}public Person createPerson(final String lastName,final String firstName,final Gender gender){// implementation goes here...}public Person createPerson(final String lastName,final String firstName,final EmploymentStatus employmentStatus){// implementation goes here...}

我要提到的最后一个缺点与使用方法重载来解决与方法或构造函数的参数过多有关的问题有关,这种方法将来可能导致大量的维护工作。 每当添加或删除或什至更改该类的属性(构造函数)或方法的参数,甚至可能需要单独检查并可能更改多个构造函数和/或方法。

结论

重载方法确实有其位置,并且可以是为客户端提供更易理解和可读的方法和构造函数的便捷方法。 但是,我发现这种方法是“最佳”方法,其频率比已经介绍的其他方法( 自定义类型 , 参数对象 , 构建器 )少,甚至比我打算介绍的某些方法(例如不同的方法和方法)少。相同方法和构造函数的显式命名版本)。 通过将方法重载与其他一些方法结合使用,可以减少方法重载方法的某些局限性和缺点。 例如, 自定义类型和参数对象的使用可以显着提高一个人的能力,使其能够更狭窄地定制重载方法或构造函数的各种版本,以使其符合要求。

参考: Java方法中的参数太多,第4部分:来自JCG合作伙伴 Dustin Marx的重载,来自Inspired by Actual Events博客。

翻译自: https://www.javacodegeeks.com/2013/10/too-many-parameters-in-java-methods-part-4-overloading.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android paint 圆角 绘制_[BOT] 一种android中实现“圆角矩形”的方法

内容简介文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角。思路是利用“Xfermode Path”来进行Bitmap的裁剪。背景圆角矩形实现的方法应该很多,网上一大堆。很怀疑为啥安卓的控件不内置这样的属…

解决高度塌陷问题

所谓高度塌陷就是在文档流中,父元素的高度默认是被子元素撑开的,也就是子元素多高,父元素就多高。但是当为子元素设置浮动以后,子元素会完全脱离文档流,此时将会导致子元素无法撑起父元素的高度,导致父元素…

HDU2035 - 人见人爱A^B

求A^B的最后三位数表示的整数。 说明&#xff1a;A^B的含义是“A的B次方” Input 输入数据包含多个测试实例&#xff0c;每个实例占一行&#xff0c;由两个正整数A和B组成&#xff08;1<A,B<10000&#xff09;&#xff0c;如果A0, B0&#xff0c;则表示输入数据的结束&…

Cisco TrustSec(理解)

1、Cisco TrustSec的限制当指定了无效的设备ID时&#xff0c;受保护的访问凭据&#xff08;Protected access credential&#xff0c;PAC&#xff09;设置将失败并保持挂起状态。 即使在清除PAC并配置正确的设备ID和密码后&#xff0c;PAC仍然会失败。作为解决方法&#xff0c;…

Java 8仍然需要LINQ吗? 还是比LINQ更好?

长期以来&#xff0c; LINQ是.NET软件工程生态系统中发生的最好的事情之一。 通过在Visual Studio 2008中引入lambda表达式和monads &#xff0c;它使C&#xff03;语言比Java&#xff08;当时的版本6&#xff09;更先进&#xff0c;并且仍在讨论泛型类型擦除的优缺点。 这项成…

web前端(12)—— 页面布局2

本篇博文&#xff0c;主要就讲定位的问题&#xff0c;也就是页面布局里最重要的&#xff0c;本篇博文不出意外的话&#xff0c;也是css的最后一篇博文了 定位&#xff0c;position属性 定位有三种&#xff1a; 相对定位绝对定位固定定位 相对定位&#xff0c;position&#x…

51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

题目链接 \(Description\) 给定一棵树。每次询问给定\(a\sim b,c\sim d\)两个下标区间&#xff0c;从这两个区间中各取一个点&#xff0c;使得这两个点距离最远。输出最远距离。\(n,q\leq10^5\)。 \(Solution\) 一个集合直径的两端点&#xff0c;在被划分为两个集合后一定是两个…

Web应用程序中的Spring JDBC入门

在上一篇文章中&#xff0c;我已经向您展示了如何设置基本的Spring 3 MVC Web应用程序 。 重复使用该项目设置作为模板&#xff0c;我将向您展示如何增强它以与JDBC一起使用。 有了它&#xff0c;您可以存储和检索数据库中的数据。 我们将通过Spring添加一个新的控制器和一个数…

python pyplot中axis_Python Pyplot xaxis未显示在图形上

pyplot未在图形上显示x轴&#xff1a;import pandas as pdimport matplotlib.pyplot as pltdf pd.read_csv(sitka_weather_2014.csv)df[AKST] pd.to_datetime(df.AKST)df[Dates] df[AKST].dt.strftime(%b %d, %Y)df.set_index("Dates", inplace True)# Plot Dataf…

为什么dubbo的调用重试不建议设置成超过1

前面提到过&#xff0c;重试是靠ClusterInvoker来保证的&#xff0c;不同的Cluster在调用失败的时候 做不同处理 比如默认的FailoverClusterInvoke的doInvoke方法里面&#xff1a;int len getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Co…

web前端入门学习(纯干货)

web前端怎么样才能入门&#xff0c;首先我们要从什么是初级web前端工程师说起&#xff1a; 按照我的想法&#xff0c;我把前端工程师分为了入门、初级、中级、高级这四个级别&#xff0c; 入门级别指的是了解什么是前端&#xff08;前端到底是什么其实很多人还是不清楚的&…

用BlockingExecutor限制任务提交

JDK的java.util.concurrent.ThreadPoolExecutor允许您将任务提交到线程池&#xff0c;并使用BlockingQueue来保存提交的任务。 如果您要提交数千个任务&#xff0c;请指定一个“绑定”队列&#xff08;即最大容量的队列&#xff09;&#xff0c;否则JVM可能会耗尽内存。 您可以…

[校内模拟题2]

水题 但是原地螺旋炸裂 都不好意思贴代码了QWQ enc 【问题背景】 zhx 和他的妹子聊天。 【问题描述】 考虑一种简单的加密算法。假定所有句子都由小写英文字母构成&#xff0c; 对于每一个字母&#xff0c; 我们将它唯一地映射到另一个字母。 例如考虑映射规则&#xff1a;a-&g…

AJAX初识(原生JS版AJAX和Jquery版AJAX)

一、什么是JSON 1.介绍JSON独立于语言&#xff0c;是一种与语言无关的数据格式。JSON指的是JavaScript对象表示法&#xff08;JavaScript Object Notation&#xff09;JSON是轻量级的文本数据交换格式JSON具有自我描述性&#xff0c;更易理解JSON使用JavaScript语法来描述数据对…

python保存为xlsb_Read XLSB File in Pandas Python

问题There are many questions on this, but there has been no simple answer on how to read an xlsb file into pandas. Is there an easy way to do this?回答1:Hi actually there is a way. Just use pyxlsb library.import pandas as pdfrom pyxlsb import open_workboo…

内存不足而没有OutOfMemoryError

这实际上是最初发布于2010年的帖子的转世。 昨天&#xff0c;当听到我们的工程师咒骂一个特别令人讨厌的错误时&#xff0c;闪回发生了。 当诅咒停止时&#xff0c;我走过去核实我的怀疑。 瞧&#xff0c;我是正确的–情绪波动是由应用程序用尽了堆空间导致的&#xff0c;但死于…

人工智能第二星期总结-------纵里寻它千百度

2018-07-28 第二周&#xff1a; 此时此刻我怀着无比沉重的心情在这里做一周的学习检讨工作 这星期依此就开始讲到了函数&#xff0c;话说函数可是python里面的钟头戏&#xff0c;不仅可以节约代码&#xff0c;还可以把代码重复使用&#xff0c;只要后面轻轻松松就可以搞定啦&am…

个人作业——软件产品案例分析

个人作业——软件产品案例分析 第一部分 调研&#xff0c;评测 评测&#xff1a; 第一次上手体验 第一眼看上去功能很全面&#xff0c;但是到点开来发现功能大部分没有实现&#xff0c;体验不太好。 缺陷Bug情况 课表查询 bug描述&#xff1a;课表查询没有课表结果,点进去当前周…

java hashtable put_Java Hashtable put()方法与示例

哈希表类put()方法put()方法在java.util包中可用。put()方法用于将给定的键元素(key_ele)放入给定的值元素(val_ele)。put()方法是一个非静态方法&#xff0c;只能通过类对象访问&#xff0c;如果尝试使用类名访问该方法&#xff0c;则会收到错误消息。put()方法在放置键/值对时…

HTML之表单

表单&#xff1a; 表单是一个包含表单元素的区域。 表单元素是允许用户在表单中输入内容,比如&#xff1a;文本域(textarea)、下拉列表、单选框(radio-buttons)、复选框(checkboxes)等等。 表单使用表单标签 <form> 来设置: <form> . input 元素 . </form>…