1.需求
仅一次方法调用就能返回多个不同类型对象。大家应该经常遇到这样的需求,但是就我们所知的return语句只允许返回单个对象。
2.解决方案
方案一:
直接控制方法值返回Map<String,Object>对象,每次在方法返回对象时,动态创建所需要返回的多个对象的对象Map集合。
方案二:
创建一个对象,用它来持有想要返回的多个对象,需要在每次需要的时候,专门创建一个类来完成这样的工作。
方案三:
通过泛型的创建一个元组类库,一次性解决该问题,以后可直接使用该类库作为返回对象。同时,我们在编译器就能确保类型安全。具体介绍一下元组的概念。
3.方案三具体解决方案
元组:将一组对象直接打包存储于其中的一个单一的对象,这个容器对象允许读取其中元素,但是不允许向其中存放新的对象。(也称为数据传递对象或者信使)
通常,元组可以具有任意长度,同时,元组对象可以是任意不同的类型,不过我们希望能够为对象指明其类型,并且从容器中读取出来时,可以得到正确的类型,要处理不同长度的问题,需要创建多个不同的元组,如下例子是一个二维选组对象,它可以保存两个任意类型的对象,并且隐含的保持了其中元素的次序。
/**
* 两对象元组基类
*
* @param <A> 泛型对象A
* @param <B> 泛型对象B
* @author Alex
*/
public class TwoTupleBase<A, B> {
public final A first;
public final B second;
public TwoTupleBase(A a, B b) {
this.first = a;
this.second = b;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
@Override
public String toString() {
return "TwoTupleBase{" +
"first=" + first +
", second=" + second +
'}';
}
}
分析一下上面的元组基类,我们之所以使用public修饰符而没有使用private修饰符,原因如下:客户端程序可以读取到first和second对象,然后可以随心所欲的使用这两个对象,但是它们却无法将其他值赋予first或者second,因为变量对象使用了final声明。
另外还有一种设计考虑,即你希望允许客户端改变first和second所引用的对象,如果想要使用具有不同元素的元组,就像只要求它们创建一个新的TwoTuple对象。
当然也可以使用private修饰符修饰,使用get方法获取。
之后我们可以利用继承机制实现长度更长的元组,组成所需要的元组基类。如:
/**
* 三对象元组基类
*
* @param <A> 泛型对象A
* @param <B> 泛型对象B
* @param <C> 泛型对象C
* @author Alex
*/
public class ThreeTupleBase<A, B, C> extends TwoTupleBase<A, B> {
public final C third;
public ThreeTupleBase(A a, B b, C third) {
super(a, b);
this.third = third;
}
public C getThird() {
return third;
}
@Override
public String toString() {
return "ThreeTupleBase{" +
"third=" + third +
", first=" + first +
", second=" + second +
'}';
}
}
在我们使用元组的时候,只需选择长度合适的元组,将其作为方法的返回值,然后在return语句中创建该元组,并返回即可。如: