Java 同時返回多個不同類型的方法


Java 同時返回多個不同類型的方法

前言:雖然對於這種需求不常用,且比較冷門,但是還是有其存在的價值,再次做一下整理。我們常用的return語句只允許返回單個對象,相對的解決辦法就是創建一個對象,用它來持有想要返回的多個對象。

  實現這種功能,還要歸功於Java1.5的新特性-泛型,我們利用泛型,可以一次性地解決該問題,以后再也不用在這個問題上浪費時間了,並且,我們可以再編譯期就能夠確保類型安全。

  你也許已經想到使用集合可以實現我們的需求,但是雖然一次可以返回多個值,但是其類型都是相同的,並不完全符合我們的需求。

  我們需要引入一個概念:元組(tuple),元組也稱為數據傳送對象或信使。元組是將一組對象直接打包存儲於其中的一個單一對象,這個容器對象允許讀取其中元素,但是不允許向其中存放新的對象。

  通常,元組可以具有任意長度,同時元組中的對象可以是任意不同的類型。我們能夠為每一個對象指明其類型,並且可以正確讀取到數據,這就是元組可以提供的功能。我們要處理不同長度的問題,需要創建多個不同的元組。

首先我們創建一個2維元組:

  1.  
    //: net/mindview/util/TwoTuple.java(Java編程思想_代碼_目錄)
  2.  
    package net.mindview.util;
  3.  
     
  4.  
    public class TwoTuple<A, B> {
  5.  
    public final A first;
  6.  
    public final B second;
  7.  
    public TwoTuple(A a, B b) {
  8.  
    first = a;
  9.  
    second = b;
  10.  
    }
  11.  
    public String toString() {
  12.  
    return "(" + first + ", " + second + ")";
  13.  
    }
  14.  
    }

構造器捕獲了要存儲的對象,而toString()方法是一個便利函數,用來顯示列表中的值。

注意:元組隱含地保持了其中元素的次序。

  閱讀上面的代碼,以及根據元組的定義,你一定會感到詫異,設計思路不是應該將first和second聲明為private,然后生成這兩個變量的get方法嗎?
  以上是我們大多數人的思維,但是我們仔細分析上面的代碼,可以發現完全符合我們的要求。首先我們可以讀取first和second,並且因為使用了final聲明,我們就無法在修改其值。我們對比這兩種寫法,很顯然,上面給出的代碼更加合理,更加簡潔明了。

  還有另一種設計考慮,即你確實希望允許客戶端程序員改變first或second所引用的對象。然而,采用上面的形式無疑是更安全的做法,這樣的話,如果程序員想要使用具有不同元素的元組,就強制要求他們另外創建一個新的TwoTuple對象。

我們可以利用繼承機制實現長度更長的元組:

  1.  
    //: net/mindview/util/ThreeTuple.java
  2.  
    package net.mindview.util;
  3.  
     
  4.  
    public class ThreeTuple<A,B,C> extends TwoTuple<A,B> {
  5.  
    public final C third;
  6.  
    public ThreeTuple(A a, B b, C c) {
  7.  
    super(a, b);
  8.  
    third = c;
  9.  
    }
  10.  
    public String toString() {
  11.  
    return "(" + first + ", " + second + ", " + third +")";
  12.  
    }
  13.  
    }
  1.  
    //: net/mindview/util/FourTuple.java
  2.  
    package net.mindview.util;
  3.  
     
  4.  
    public class FourTuple<A,B,C,D> extends ThreeTuple<A,B,C> {
  5.  
    public final D fourth;
  6.  
    public FourTuple(A a, B b, C c, D d) {
  7.  
    super(a, b, c);
  8.  
    fourth = d;
  9.  
    }
  10.  
    public String toString() {
  11.  
    return "(" + first + ", " + second + ", " +
  12.  
    third + ", " + fourth + ")";
  13.  
    }
  14.  
    }
  1.  
    //: net/mindview/util/FiveTuple.java
  2.  
    package net.mindview.util;
  3.  
     
  4.  
    public class FiveTuple<A,B,C,D,E>
  5.  
    extends FourTuple<A,B,C,D> {
  6.  
    public final E fifth;
  7.  
    public FiveTuple(A a, B b, C c, D d, E e) {
  8.  
    super(a, b, c, d);
  9.  
    fifth = e;
  10.  
    }
  11.  
    public String toString() {
  12.  
    return "(" + first + ", " + second + ", " +
  13.  
    third + ", " + fourth + ", " + fifth + ")";
  14.  
    }
  15.  
    }

為了使用元組,你只需定義一個長度適合的元組,將其作為方法的返回值,然后在return語句中創建該元組,並返回即可。

實例:

  1.  
    //: generics/TupleTest.java
  2.  
    import net.mindview.util.*;
  3.  
     
  4.  
    class Amphibian {
  5.  
    }
  6.  
    class Vehicle {
  7.  
    }
  8.  
     
  9.  
    public class TupleTest {
  10.  
    static TwoTuple<String, Integer> f() {
  11.  
    // Autoboxing converts the int to Integer:
  12.  
    return new TwoTuple<String, Integer>("hi", 47);
  13.  
    }
  14.  
    static ThreeTuple<Amphibian, String, Integer> g() {
  15.  
    return new ThreeTuple<Amphibian, String, Integer>(new Amphibian(), "hi",
  16.  
    47);
  17.  
    }
  18.  
    static FourTuple<Vehicle, Amphibian, String, Integer> h() {
  19.  
    return new FourTuple<Vehicle, Amphibian, String, Integer>(new Vehicle(),
  20.  
    new Amphibian(), "hi", 47);
  21.  
    }
  22.  
    static FiveTuple<Vehicle, Amphibian, String, Integer, Double> k() {
  23.  
    return new FiveTuple<Vehicle, Amphibian, String, Integer, Double>(
  24.  
    new Vehicle(), new Amphibian(), "hi", 47, 11.1);
  25.  
    }
  26.  
    public static void main(String[] args) {
  27.  
    TwoTuple<String, Integer> ttsi = f();
  28.  
    System.out.println(ttsi);
  29.  
    // ttsi.first = "there"; // Compile error: final
  30.  
    System.out.println(g());
  31.  
    System.out.println(h());
  32.  
    System.out.println(k());
  33.  
    }
  34.  
    }

輸出結果:

  1.  
    (hi, 47)
  2.  
    (Amphibian@15db9742, hi, 47)
  3.  
    (Vehicle@6d06d69c, Amphibian@7852e922, hi, 47)
  4.  
    (Vehicle@4e25154f, Amphibian@70dea4e, hi, 47, 11.1)

  由於有了泛型,你可以很容易地創建元組,令其返回一組任意類型的對象。而你所要做的,只是編寫表達式而已。

  通過ttsi.first = "there";語句的錯誤,我們可以看出,final聲明確實能夠保護public元素,在對象被構造出來之后,聲明為final的元素便不能被再賦予其他值了。

參考資料:

  • 《Java編程思想》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM