Java 同时返回多个不同类型的方法
前言:虽然对于这种需求不常用,且比较冷门,但是还是有其存在的价值,再次做一下整理。我们常用的return语句只允许返回单个对象,相对的解决办法就是创建一个对象,用它来持有想要返回的多个对象。
实现这种功能,还要归功于Java1.5的新特性-泛型,我们利用泛型,可以一次性地解决该问题,以后再也不用在这个问题上浪费时间了,并且,我们可以再编译期就能够确保类型安全。
你也许已经想到使用集合可以实现我们的需求,但是虽然一次可以返回多个值,但是其类型都是相同的,并不完全符合我们的需求。
我们需要引入一个概念:元组(tuple),元组也称为数据传送对象或信使。元组是将一组对象直接打包存储于其中的一个单一对象,这个容器对象允许读取其中元素,但是不允许向其中存放新的对象。
通常,元组可以具有任意长度,同时元组中的对象可以是任意不同的类型。我们能够为每一个对象指明其类型,并且可以正确读取到数据,这就是元组可以提供的功能。我们要处理不同长度的问题,需要创建多个不同的元组。
首先我们创建一个2维元组:
- //: net/mindview/util/TwoTuple.java(Java编程思想_代码_目录)
- package net.mindview.util;
- public class TwoTuple<A, B> {
- public final A first;
- public final B second;
- public TwoTuple(A a, B b) {
- first = a;
- second = b;
- }
- public String toString() {
- return "(" + first + ", " + second + ")";
- }
- }
构造器捕获了要存储的对象,而toString()方法是一个便利函数,用来显示列表中的值。
注意:元组隐含地保持了其中元素的次序。
阅读上面的代码,以及根据元组的定义,你一定会感到诧异,设计思路不是应该将first和second声明为private,然后生成这两个变量的get方法吗?
以上是我们大多数人的思维,但是我们仔细分析上面的代码,可以发现完全符合我们的要求。首先我们可以读取first和second,并且因为使用了final声明,我们就无法在修改其值。我们对比这两种写法,很显然,上面给出的代码更加合理,更加简洁明了。
还有另一种设计考虑,即你确实希望允许客户端程序员改变first或second所引用的对象。然而,采用上面的形式无疑是更安全的做法,这样的话,如果程序员想要使用具有不同元素的元组,就强制要求他们另外创建一个新的TwoTuple对象。
我们可以利用继承机制实现长度更长的元组:
- //: net/mindview/util/ThreeTuple.java
- package net.mindview.util;
- public class ThreeTuple<A,B,C> extends TwoTuple<A,B> {
- public final C third;
- public ThreeTuple(A a, B b, C c) {
- super(a, b);
- third = c;
- }
- public String toString() {
- return "(" + first + ", " + second + ", " + third +")";
- }
- }
- //: net/mindview/util/FourTuple.java
- package net.mindview.util;
- public class FourTuple<A,B,C,D> extends ThreeTuple<A,B,C> {
- public final D fourth;
- public FourTuple(A a, B b, C c, D d) {
- super(a, b, c);
- fourth = d;
- }
- public String toString() {
- return "(" + first + ", " + second + ", " +
- third + ", " + fourth + ")";
- }
- }
- //: net/mindview/util/FiveTuple.java
- package net.mindview.util;
- public class FiveTuple<A,B,C,D,E>
- extends FourTuple<A,B,C,D> {
- public final E fifth;
- public FiveTuple(A a, B b, C c, D d, E e) {
- super(a, b, c, d);
- fifth = e;
- }
- public String toString() {
- return "(" + first + ", " + second + ", " +
- third + ", " + fourth + ", " + fifth + ")";
- }
- }
为了使用元组,你只需定义一个长度适合的元组,将其作为方法的返回值,然后在return语句中创建该元组,并返回即可。
实例:
- //: generics/TupleTest.java
- import net.mindview.util.*;
- class Amphibian {
- }
- class Vehicle {
- }
- public class TupleTest {
- static TwoTuple<String, Integer> f() {
- // Autoboxing converts the int to Integer:
- return new TwoTuple<String, Integer>("hi", 47);
- }
- static ThreeTuple<Amphibian, String, Integer> g() {
- return new ThreeTuple<Amphibian, String, Integer>(new Amphibian(), "hi",
- 47);
- }
- static FourTuple<Vehicle, Amphibian, String, Integer> h() {
- return new FourTuple<Vehicle, Amphibian, String, Integer>(new Vehicle(),
- new Amphibian(), "hi", 47);
- }
- static FiveTuple<Vehicle, Amphibian, String, Integer, Double> k() {
- return new FiveTuple<Vehicle, Amphibian, String, Integer, Double>(
- new Vehicle(), new Amphibian(), "hi", 47, 11.1);
- }
- public static void main(String[] args) {
- TwoTuple<String, Integer> ttsi = f();
- System.out.println(ttsi);
- // ttsi.first = "there"; // Compile error: final
- System.out.println(g());
- System.out.println(h());
- System.out.println(k());
- }
- }
输出结果:
- (hi, 47)
- (Amphibian@15db9742, hi, 47)
- (Vehicle@6d06d69c, Amphibian@7852e922, hi, 47)
- (Vehicle@4e25154f, Amphibian@70dea4e, hi, 47, 11.1)
由于有了泛型,你可以很容易地创建元组,令其返回一组任意类型的对象。而你所要做的,只是编写表达式而已。
通过ttsi.first = "there";语句的错误,我们可以看出,final声明确实能够保护public元素,在对象被构造出来之后,声明为final的元素便不能被再赋予其他值了。
参考资料:
- 《Java编程思想》
Java 同时返回多个不同类型的方法的更多相关文章
- Java连载76-基础数据类型包装类型及其方法简介
一.java中八种基本数据类型对应的包装类型 基本数据类型 包装类型 byte java.lang.Byte short ...
- java将long数据转为int类型的方法
二.调用intValue()方法 [java] long ll = 300000; int ii= new Long(ll).intValue(); 三.先把long转换成字符串String,然后在转 ...
- java反射三种获得类类型的方法
public class Test { public static void main(String[] args) { Test t=new Test();//所有的类都是Class类的实例(类类型 ...
- Java中返回参数值的几种状态
Java 中无参无返回值方法的使用 第一步,定义方法 例如:下面代码定义了一个方法名为 show ,没有参数,且没有返回值的方法,执行的操作为输出 " welcome to imooc. & ...
- Java协变返回类型
今天看到句话:“支持重写方法时返回协变类型”. 那么什么事协变类型?在网上找了找资料,大体上明白了. Java 5.0添加了对协变返回类型的支持,即子类覆盖(即重写)基类方法时,返回的类型可以是基类方 ...
- “全栈2019”Java第五十八章:多态中方法返回类型可以是子类类型
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Java中返回值定义为int类型的 方法return 1返回的是int还是Integer&&finally中return问题
在Java中返回值定义为int类型的 方法return 1:中返回的是Integer值,在返回的时候基本类型值1被封装为Integer类型. 定义一个Test类,在异常处理try中和finally中分 ...
- Java常见面试题02-方法重写和方法重载的区别?方法重载能改变返回值类型吗?
方法重写和方法重载的区别?方法重载能改变返回值类型吗? A:Override方法重写和Overload方法重载的区别? Overload是否可以改变返回值类型?可以 方法重写 • 子类中 ...
- java统一返回标准类型
一.前言.背景 在如今前后端分离的时代,后端已经由传统的返回view视图转变为返回json数据,此json数据可能包括返回状态.数据.信息等......因为程序猿的习惯不同所以返回json数据的格式也 ...
随机推荐
- win7 资源资源管理器访问FTP站点
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\ftp] @="URL:File Transfer Protocol" ...
- Javascript日常编码中的一些常见问题
一.尽量少用全局变量 这是一个疑问最少,同时流传最 广的一条.Javascript使用函数管理作用域,全局变量最大的问题在于同名变量冲突.这种隐患产生比较直接的两个原因就是Javascript语言 ...
- 码云 使用 汉化 GitHub
enhancement 增强feature 功能duplicate 重复的invalid 无效的wontfix 无法修改 不处理 ===== Wiki 主要是您项目的文档(说明, 状态)等等. 该项目 ...
- [CodeVS4438]YJQ Runs Upstairs
[CodeVS4438]YJQ Runs Upstairs 题目大意: 一个\(n(n\le50)\)个点\(m(m\le300)\)条边的DAG,保证从\(1\)到\(n\)的所有路径经过边数均小于 ...
- java中的文件下载
package com.pb.down;import java.io.File;import java.io.FileInputStream;import java.io.IOException; i ...
- Java 中的“implements Runnable” 和“extends Thread”(转)
知识点 “implements Runnable” 和“extends Thread”的不同 具体分析 最近在学习Android中的Handler消息传递机制时,创建新线程有两种方式:一种是实现Run ...
- 关于php开发中的字符编码问题总结的几个要点
用php这么久,今天终于要彻底总结下php乱码问题,因为实在是吃过不少亏啊 1:header("content-type:text/html;charset=utf-8")或者&l ...
- Asp.Net Core异常处理整理
目前版本是Asp.Net Core v1.1,这个版本的感觉对Http请求中的错误处理方便不是很完善. 没有HttpException异常类,不能在任何的地方自由的抛出对应的异常状态. 一.默认的异常 ...
- HTML5新特性[ Notifications ] 桌面消息
在执行完以上代码后,我们就成功地创建了一个消息框实例,在Chrome下面它最终会显示成这样: 到这里我们已经成功了一半,但能不能正确地显示出这个消息框,最终还取决于用户的授权.鉴于浏览器的安全机制,只 ...
- 启动vmware虚拟机报错:“无法获得VMCI驱动程序的版本:句柄无效”
启动vmware虚拟机的时候报错: 找到对应虚拟机的文件夹路径: 用记事本打开CentOS 64位.vmx,找到这么一行: vmci0.present = "TRUE" 把TRUE ...