zoukankan      html  css  js  c++  java
  • 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编程思想》
  • 相关阅读:
    弹出窗口插件
    多彩百分比 动态进度条 投票效果显示(jquery)
    Oracle EBS Shipping(WSH)模块日志收集方法
    自动创建采购订单提示汇率值无效
    Using API FND_PROFILE.save to update profile from backend (转)
    二手房怎么买不会吃亏 八大高招教您投资理财
    删除list中的元素
    Create Stock Locator By Using API(EBS R12)
    Oracle EBS中查询Profile的各种SQL
    与账户别名相关的表
  • 原文地址:https://www.cnblogs.com/hfultrastrong/p/10018683.html
Copyright © 2011-2022 走看看