java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回
java方法帶參數返回值
在當前的系列文章中,我正在致力于減少調用Java方法和構造函數所需的參數數量,到目前為止,我一直專注于直接影響參數本身的方法( 自定義類型 , 參數對象 , 構建器模式 , 方法重載和方法命名 )。 鑒于此,對于本系列中的一篇文章,我專門討論Java方法如何提供返回值似乎讓我感到驚訝。 但是,方法的返回值會影響開發人員選擇通過設置或更改提供的參數(而不是附加或添加更傳統的方法返回機制)來提供“返回”值時方法所接受的參數。
非構造方法返回值的“傳統方式”都可以在方法簽名中指定。 從Java方法返回值的最常見的方法是通過其聲明的return type 。 這通常效果很好,但是最常見的一種挫敗是允許它僅從 Java方法返回一個值 。
Java的異常處理機制也是將方法的“結果”保留給調用方的另一種方法。 特別是, 經過檢查的異常通過throws子句通告給調用者。 實際上, Jim Waldo在他的《 Java:The Good Parts》一書中指出,當人們將Java異常視為另一種方法返回限制為Throwable類型時,更容易理解Java異常。
盡管方法的返回類型和拋出的異常旨在作為方法將信息返回給調用方的主要方法,但有時仍傾向于通過傳遞給方法的參數來返回數據或狀態。 當一個方法需要返回多個信息時,Java方法的單值返回似乎是有限的。 盡管例外提供了另一種與呼叫者進行通信的方式,但似乎幾乎所有人都同意,例外應僅用于報告異常情況,而不能用于報告“正常”數據或在控制流中使用。 鑒于只能從一個方法返回一個對象或原語,并且異常僅允許返回Throwable且應僅將其用于報告異常情況,因此Java開發人員劫持參數作為返回數據的替代途徑變得越來越有吸引力給來電者。
開發人員可以用來將方法參數用作返回數據的載體的技術是接受可變的參數并改變傳入對象的狀態。 這些可變對象可以通過方法更改其內容,然后調用者可以訪問它提供的對象以確定已被調用方法應用的新狀態設置。 盡管可以使用任何可變對象來完成此操作,但對于試圖通過參數將值傳遞回調用方的開發人員而言,集合似乎特別有吸引力。
通過提供的參數將狀態傳遞回被調用有一些缺點。 由于大多數Java開發人員可能期望參數傳入而不是傳出(并且Java不提供任何代碼支持來指定差異),因此這種方法通常違反了使您驚訝的原則 。 鮑勃·馬丁(Bob Martin)在他的《 清潔代碼 》一書中這樣寫道 :“通常,應避免使用輸出參數。” 使用參數作為方法向調用者提供狀態或輸出的方法的另一個缺點是,這會增加傳遞給方法的參數的混亂程度。 考慮到這一點,本文的其余部分重點介紹通過傳入的參數返回多個值的替代方法。
盡管Java方法只能返回單個對象或基元,但是當人們認為一個對象可以是我們想要的任何對象時,這實際上并不是什么限制。 我見過幾種方法,但不推薦使用。 其中之一是返回對象實例的數組或集合,而每個Object都是一個完全不同且通常不相關的“事物”。 例如,該方法可能返回三個值作為數組或集合的三個元素。 此方法的一種變體是使用一對元組或n大小的元組返回多個關聯值。 此方法的另一個變體是返回Java Map,該Java Map將任意鍵映射到它們的關聯值。 與其他解決方案一樣,此方法會給客戶端帶來不必要的負擔,讓他們知道那些鍵是什么,并通過這些鍵訪問映射值。
下一個代碼清單包含幾種不那么吸引人的方法,這些方法用于返回多個值而不會劫持方法參數以返回多個值。
通過通用數據結構返回多個值
// ===============================================================// NOTE: These examples are intended solely to illustrate a point// and are NOT recommended for production code.// ===============================================================/*** Provide movie information.* * @return Movie information in form of an array where details are mapped to* elements with the following indexes in the array:* 0 : Movie Title* 1 : Year Released* 2 : Director* 3 : Rating*/public Object[] getMovieInformation(){final Object[] movieDetails ={"World War Z", 2013, "Marc Forster", "PG-13"};return movieDetails;}/*** Provide movie information.* * @return Movie information in form of a List where details are provided* in this order: Movie Title, Year Released, Director, Rating.*/public List<Object> getMovieDetails(){return Arrays.<Object>asList("Ender's Game", 2013, "Gavin Hood", "PG-13");}/*** Provide movie information.* * @return Movie information in Map form. Characteristics of the movie can* be acquired by looking in the map for these key elements: "Title", "Year",* "Director", and "Rating"./*/public Map<String, Object> getMovieDetailsMap(){final HashMap<String, Object> map = new HashMap();map.put("Title", "Despicable Me 2");map.put("Year", 2013);map.put("Director", "Pierre Coffin and Chris Renaud");map.put("Rating", "PG");return map;}上面顯示的方法確實滿足了不通過調用的方法的參數將數據傳遞回調用方的意圖,但是在調用方上仍然沒有不必要的負擔來了解返回數據結構的詳細信息。 減少方法的參數數量并且不違反最小驚喜原則是很好的,但是要求客戶知道復雜數據結構的復雜性并不是很好。
當我需要返回多個值時,我更喜歡為返回值編寫自定義對象。 與使用數組,集合或元組結構相比,這需要做更多的工作,但是很少的額外工作(對于現代Java IDE,通常只有幾分鐘的時間)會帶來可讀性和流利性,而這是這些更通用的方法所不具備的。 我的自定義返回對象不必在Javadoc上進行解釋或要求我的代碼的用戶仔細閱讀我的代碼,以了解在數組或集合中按哪個順序提供了哪些參數,或者在元組中以哪個值提供了這些參數,而無需為我的自定義返回對象定義方法他們告訴客戶確切他們提供什么。
接下來的代碼片段說明了一個主要由NetBeans生成的簡單Movie類,該類可以用作返回類型,并且可以返回該類的實例的代碼,而不是更通用,更不易理解的數據結構。
電影.java
package dustin.examples;import java.util.Objects;/*** Simple Movie class to demonstrate how easy it is to provide multiple values* in a single Java method return and provide readability to the client.* * @author Dustin*/ public class Movie {private final String movieTitle;private final int yearReleased;private final String movieDirectorName;private final String movieRating;public Movie(String movieTitle, int yearReleased, String movieDirectorName, String movieRating){this.movieTitle = movieTitle;this.yearReleased = yearReleased;this.movieDirectorName = movieDirectorName;this.movieRating = movieRating;}public String getMovieTitle(){return movieTitle;}public int getYearReleased(){return yearReleased;}public String getMovieDirectorName(){return movieDirectorName;}public String getMovieRating(){return movieRating;}@Overridepublic int hashCode(){int hash = 3;hash = 89 * hash + Objects.hashCode(this.movieTitle);hash = 89 * hash + this.yearReleased;hash = 89 * hash + Objects.hashCode(this.movieDirectorName);hash = 89 * hash + Objects.hashCode(this.movieRating);return hash;}@Overridepublic boolean equals(Object obj){if (obj == null){return false;}if (getClass() != obj.getClass()){return false;}final Movie other = (Movie) obj;if (!Objects.equals(this.movieTitle, other.movieTitle)){return false;}if (this.yearReleased != other.yearReleased){return false;}if (!Objects.equals(this.movieDirectorName, other.movieDirectorName)){return false;}if (!Objects.equals(this.movieRating, other.movieRating)){return false;}return true;}@Overridepublic String toString(){return "Movie{" + "movieTitle=" + movieTitle + ", yearReleased=" + yearReleased + ", movieDirectorName=" + movieDirectorName + ", movieRating=" + movieRating + '}';} }在單個對象中返回多個詳細信息
/*** Provide movie information.* * @return Movie information.*/public Movie getMovieInfo(){return new Movie("Oblivion", 2013, "Joseph Kosinski", "PG-13");}Movie課的簡單寫作花了我大約5分鐘的時間。 我使用NetBeans類創建向導來選擇類名稱和包,然后鍵入該類的四個屬性。 從那里開始,我僅使用NetBeans的“插入代碼”機制來插入“獲取”訪問器方法以及重寫的toString() , hashCode()和equals(Object)方法。 如果我認為不需要這些,可以簡化類,但按原樣創建確實很容易。 現在,我有一個更有用的返回類型,這由使用該類的代碼反映出來。 它幾乎不需要在返回類型上使用Javadoc注釋,因為該類型可以說明一切,并使用“ get”方法發布其內容。 我認為,與通過方法參數返回狀態或使用更通用且更難使用的返回數據結構之類的替代方法相比,創建這些簡單的類以返回多個值的少量額外工作將獲得豐厚的回報。
保留要返回給調用方的多個值的自定義類型是一種有吸引力的解決方案,這并不奇怪。 畢竟,從概念上講,這與我之前寫過的關于使用自定義類型和參數對象傳遞多個相關參數而不是單獨傳遞它們的概念非常相似。 Java是一種面向對象的語言,當我沒有看到Java代碼中使用對象來組織好參數并在一個不錯的包中返回值時,它使我感到驚訝。
優勢與優勢
使用自定義參數對象表示和封裝多個返回值的優點是顯而易見的。 方法的參數可以保留為“輸入”參數,因為所有輸出信息(通過異常機制傳達的錯誤信息除外)都可以在方法返回的自定義對象中提供。 與使用通用數組,集合,映射,元組或其他通用數據結構相比,這是一種更清潔的方法,因為所有這些替代方法都將開發工作轉移到了所有潛在客戶上。
成本與劣勢
我看到編寫具有多個值的自定義類型用作Java方法的返回類型的缺點很小。 也許最常聲稱的成本是編寫和測試這些類的價格,但是該成本非常小,因為這些類往往很簡單,并且因為現代IDE為我們完成了大部分工作。 因為IDE是自動執行的,所以代碼通常是正確的。 這些類非常簡單,以使代碼審閱者易于閱讀,并且易于測試。
為了尋找其他成本和缺點,人們可能會爭辯說這些類可以膨脹代碼庫和程序包,但我認為這不是一個強有力的論據。 盡管自定義類實現不好的風險很小,但我認為客戶機代碼可能會混淆更通用的返回類型的解釋。 另一個小風險是,開發人員可能將很多無關的東西扔到同一個類中,而這些項目之間的唯一關系是,相同的方法需要返回它們。 即使這樣,我能看到的唯一更好的選擇是修改代碼,而無需返回多個值。 在自定義對象中返回原本不相關的項似乎仍然比在通用數據結構中返回這組不相關的數據更好。 實際上,這些通用數據結構變得更加笨拙并且難以使用,因為它們所擁有的值變得越來越不相關。
結論
自定義類型和參數對象可幫助我們直接解決Java方法中過多參數的問題。 幸運的是,這些自定義類型和返回值對象還可以幫助我們通過自定義類型和返回值對象返回多個值,而不需要添加僅用于將輸出信息傳遞回去的附加參數,從而間接地減少所需參數的數量。呼叫者,召集者。
翻譯自: https://www.javacodegeeks.com/2013/11/too-many-parameters-in-java-methods-part-6-method-returns.html
java方法帶參數返回值
總結
以上是生活随笔為你收集整理的java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汤的英语怎么读 汤的英语念什么
- 下一篇: Java 11功能– Java飞行记录器