`

Java方法返回多种类型

    博客分类:
  • java
阅读更多

我的文章都整理添加到了个人博客中,大家可以添加这个RSS以便获得即时的文章信息。

 

说明:

1.本文讲述3种方式 如有更好方式 欢迎讨论

2.本例前准备:下载jar包:

  1. http://sourceforge.net/ 下搜索下载json-lib、ezmorph
  2. http://commons.apache.org/  下搜索下载以下jar
    lang(注意 不要使用最新的3.1 用2.6)、collections、beanutils

3.三种方式简要说明

  1. Json方式(目前web开发常用的方式)
  2. 集合方式(最容易想到)
  3. 泛型元组(最简单最实用)

4.具体内容看注释 写的很清楚,如有疑问欢迎讨论

 

1.测试类

package com.cxyapi.generics;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONObject;

/** Java方法返回多种类型
 * @author cxy @ www.cxyapi.com
 */
public class ReturnMultipleResult
{
	public static void main(String[] args)
	{
		//方式一:使用json
		JSONObject result1=ReturnMultipleResult.way1();
		System.out.println(result1);
		JSONObject jos=(JSONObject)result1.get("s");
		System.out.println(jos.get("name"));
		/* JSONObject中存放的都是Object类型(其实是JSONObject类型)
		 * 如果想使用原来的类型,还需要其他的转换方式(toBean方法)
		 * 但是toBean方法 对于 有自定义构造函数的class,还需要一个init方法或定义映射
		 * 好麻烦呀~
		 * 并且这种方式还需要导入各种jar包
		 * 但是这种方式并不是一无是处,在action/controller层面还是很好用的,不适合纯业务处理的bo层。
		 */
		System.out.println("========================");
		
		//方式二:集合
		Map<String,Object> result2=ReturnMultipleResult.way2();
		System.out.println(result2);
		for(Entry<String, Object> one: result2.entrySet())
		{
			if(one.getKey().equals("s"))
			{
				Student s=(Student)one.getValue();
				s.show();
			}else if(one.getKey().equals("t"))
			{
				Teacher t=(Teacher)one.getValue();
				t.show();
			}
		}
		/* 这种方式采用Object超级父类来擦出类型差异
		 * 但是这种方式处理起来比较复杂,你需要自己判断到底是哪种类型的,并做相应的类型转化
		 */
		System.out.println("========================");
		
		//方式三:使用泛型元组
		TwoTuple<Student, Teacher> result3=ReturnMultipleResult.way3();
		result3.first.show();
		result3.second.show();
		System.out.println(new TwoTuple<String,Integer>("cxy",1));
		//应该不用多说了吧~ 优势太明显了,不用判断,不用转型,不用导入jar包,随意更换类型
	}
	
	//方式一:使用json返回多个结果对象
	public static JSONObject way1()
	{
		Student s=new Student("小明","清华大学");
		Teacher t=new Teacher("cxyapi", "Java编程");
		JSONObject backObject=new JSONObject();
		backObject.put("s", s);
		backObject.put("t", t);
		return backObject;
	}
	
	//方式二:集合方式
	public static Map<String,Object> way2()
	{
		Student s=new Student("小明","清华大学");
		Teacher t=new Teacher("cxyapi", "Java编程");
		Map<String,Object> backObject=new HashMap<String, Object>();
		backObject.put("s", s);
		backObject.put("t", t);
		return backObject;
	}
	
	//方式二:泛型元组
	public static TwoTuple<Student, Teacher> way3()
	{
		Student s=new Student("小明","清华大学");
		Teacher t=new Teacher("cxyapi", "Java编程");
		return new TwoTuple<Student, Teacher>(s,t);
	}
}

 

    元组:

package com.cxyapi.generics;

/** 元组  可以让一个方法返回多个对象
 * @author cxy @ www.cxyapi.com
 */
public class TwoTuple<A,B>
{
	/* 定义成final 是为了保证其安全性,不能进行修改
	 * public final 比private+getter/setter更符合当前的需求
	 */
	public final A first; 
	public final B second;
	
	public TwoTuple(A a,B b)
	{
		first=a;
		second=b;
	}
	
	public static TwoTuple<String,Integer> tupleTest()
	{
		return new TwoTuple<String,Integer>("cxy",1);
	}
	
	public static void main(String[] args)
	{
		System.out.println(TwoTuple.tupleTest().first);
		System.out.println(TwoTuple.tupleTest().second);
	}
}

 

   涉及到的Student类和Teacher类

package com.cxyapi.generics;

/**
 * @author cxy @ www.cxyapi.com
 */
public class Teacher
{
	private String name; // 姓名

	private String course; // 课程

	public Teacher(String name, String course)
	{
		this.name = name;
		this.course = course;
	}
	
	public void show()
	{
		System.out.println("我叫:"+this.name+",是一名"+this.course+"教师");
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getCourse()
	{
		return course;
	}

	public void setCourse(String course)
	{
		this.course = course;
	}
}

 

package com.cxyapi.generics;

/**
 * @author cxy @ www.cxyapi.com
 */
public class Student
{
	private String name;  //姓名
	
	private String school;  //就读学校

	public Student(String name, String school)
	{
		this.name = name;
		this.school=school;
	}
	
	public Student init()
	{
		return new Student("1", "2");
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getSchool()
	{
		return school;
	}

	public void setSchool(String school)
	{
		this.school = school;
	}
	
	public void show()
	{
		System.out.println("我叫:"+this.name+",就读于"+this.school);
	}

}

 

 

声明:

1.原创文章,转载请标明并加本文连接。

2.文章反映个人愚见,如有异议欢迎讨论指正

3.更多的内容请看我的  个人博客(测试版)

8
11
分享到:
评论
34 楼 wawxy2009 2013-03-24  
领教了~多谢
33 楼 mwei 2013-03-22  
snkcxy 写道
javaseer 写道
那如果想返回345678个对象元组还有办法做吗?

呵呵 继承就可以了


在方法调用时,被调用的方法如果返回多个不同类型的对象时,使用元组是不错的选择,为此方法写好javadoc就更好了。 至于返回3,4,5,6,7,8..N个对象,这...这个方法本身就有问题了,一次返回这么多不同类型的对象不太合理,可以使用LZ所言继承,将Tuple2扩展到TupleN(无奈之举,还是重构方法)。我平时只用Tuple2,Tuple3就很少用了。 当然Scala里提供到了22个元素的元组:
public class Tuple22 <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>  implements ... {
    private final T1 _1;
    private final T2 _2;
    private final T3 _3;
    private final T4 _4;
    ...


//下面的形式就够罗嗦了,方法本身就不够合理
return new Tuple2<List<YourType>,Map<String,YourType2>>(..., ..)

吸其精华,好用即可,接受拍。
32 楼 snkcxy 2013-03-21  
rainsilence 写道

public class Test {

	private int age;

	public static void main(String[] args) throws NoSuchFieldException, SecurityException {
		System.out.println(Test.class.getDeclaredField("age").getType().isPrimitive());
	}
}


嗯 这种方式确实能获得field的类型,学习了
那再想请教一下,如何获得方法内的变量的类型(尤其是基本类型)
31 楼 snkcxy 2013-03-21  
rainsilence 写道
学习方法是挺好的,将范例代码记下来。记得我6年前也是这么做的。更新了6年,现在资料已经有1.5G了。范围涉及到java全体,javascript全体(包括css,最新的html5的最佳实践代码),opengl算法,javafx2。感觉你还是处于初级阶段。慢慢来吧

嗯 确实 是初级阶段 还望前辈多多指点~
javafx2 我也很关注 用他写了一个即时通讯的小demo javafx2做界面连消息服务器
感觉需要改进的还很多,希望java8能有更好的表现,我是很期待呢~
30 楼 snkcxy 2013-03-21  
rainsilence 写道
http://www.cxyapi.com/java/oo/final.html

这篇,关键字final可讲的多了去了

1.多线程方向
由于java语言的不是为了并发而创建的。所以会有很多多线程方面的问题。其中最常见的就是内部类引用外部对象问题

java的规避方法就是当内部类要引用外部局部变量时,必须将局部变量变成final

etc

2.设计模式方向

不变模式

3.架构方向
Constants类,Util类最好都写成final的。

晕 这些不是问题吧?(我以为您指的问题是错误了)
我说过每一个知识点 都可以扩展出很多很多东西 尤其是和oo有关的东西
我写的是java基础 或者更准确的说是java入门
这些经验 和 最佳实践的不可能枚举的清楚。。。
但是能看出来这位朋友经验丰富肯定是前辈级的,还望前辈多多指点~
29 楼 rainsilence 2013-03-21  
学习方法是挺好的,将范例代码记下来。记得我6年前也是这么做的。更新了6年,现在资料已经有1.5G了。范围涉及到java全体,javascript全体(包括css,最新的html5的最佳实践代码),opengl算法,javafx2。感觉你还是处于初级阶段。慢慢来吧
28 楼 rainsilence 2013-03-21  
http://www.cxyapi.com/java/oo/final.html

这篇,关键字final可讲的多了去了

1.多线程方向
由于java语言的不是为了并发而创建的。所以会有很多多线程方面的问题。其中最常见的就是内部类引用外部对象问题

java的规避方法就是当内部类要引用外部局部变量时,必须将局部变量变成final

etc

2.设计模式方向

不变模式

3.架构方向
Constants类,Util类最好都写成final的。
27 楼 rainsilence 2013-03-21  
snkcxy 写道
MrCrapBag 写道

反射得到某个class对象后,比如说classFoo,那么classFoo.getName()就能获取一个类的唯一标识了。

当然,在osgi动态加载的时候,还要和对应加载类的classloader一起才能唯一确定一个类

呵呵 他说的这个是我的另一篇文章http://snkcxy.iteye.com/admin/blogs/1827913
反射获得对象类型 这个我写的很清楚了
其实我们讨论的是如何获取变量的基本类型问题
1.很多朋友看成是 判断是不是基本类型,但是我的文章是讨论获取是什么 而不是是不是~
2.有些人认为我写的多态方式没有实用价值 这个我也解释了 在普通运行的时候确实没有实用价值,因为基本类型 不存在不确定性,但是在动态加载运行类的时候 这个就稍具意义了

public class Test {

	private int age;

	public static void main(String[] args) throws NoSuchFieldException, SecurityException {
		System.out.println(Test.class.getDeclaredField("age").getType().isPrimitive());
	}
}


你说的写framework的时候(即动态加载类),如果类中有一个变量定义为基本类型,通过以上方法就可以判断。如果是局部变量,int i在传入方法的时候会自动类型转换。另外,你的动态方法真是太无语了,全是冗余代码,直接用泛型就ok了。在商业项目中,你的这种做法是绝对不允许的。
26 楼 snkcxy 2013-03-21  
MrCrapBag 写道

反射得到某个class对象后,比如说classFoo,那么classFoo.getName()就能获取一个类的唯一标识了。

当然,在osgi动态加载的时候,还要和对应加载类的classloader一起才能唯一确定一个类

呵呵 他说的这个是我的另一篇文章http://snkcxy.iteye.com/admin/blogs/1827913
反射获得对象类型 这个我写的很清楚了
其实我们讨论的是如何获取变量的基本类型问题
1.很多朋友看成是 判断是不是基本类型,但是我的文章是讨论获取是什么 而不是是不是~
2.有些人认为我写的多态方式没有实用价值 这个我也解释了 在普通运行的时候确实没有实用价值,因为基本类型 不存在不确定性,但是在动态加载运行类的时候 这个就稍具意义了
25 楼 snkcxy 2013-03-21  
MrCrapBag 写道
snkcxy 写道
jjcang 写道
做个返回对象,或者数组就可以了。

嗯 其实元组的方式就是返回对象,只不过类型不是定死的
嗯 数组倒是一种方式 Object[]


java有元组的概念吗?楼主所谓的元组,其实就是对象嵌套对象的做法吧。

顺便说一下,Object[]数组这种方式很不好哦,因为你拿到返回值之后,会做向下造型,这个时候你就要知道原来的类型是什么了,那你还得缓存每个对象的类型,而且在转换的时候,也是不安全的。

对 这位朋友说的很对
java中没有明确的元组概念 这个就算是模拟吧
Object[]方式肯定不好,这里只是说可以这样做(响应一下那个位朋友的讨论),但是真实情况下肯定不会去用Object去做这些事情。方式繁琐且不安全
24 楼 snkcxy 2013-03-21  
我觉得咱们讨论归讨论,每个人有自己的应用领域 所以对知识点的认知也不太一样
我不可能说出一个知识点的方方面面的应用,大家一起讨论讨论技术挺好
但是没必要 说 什么闭门造车,水平低啥的,每个人都有每个人的道理,谁对谁错都不一定,因为加载 “大环境” 的情况下,一切皆有可能~
当然 如果真的是哪里错了 我肯定虚心接受~
23 楼 snkcxy 2013-03-21  
MrLee23 写道
snkcxy 写道
MrLee23 写道
楼主的元组,不就是java中的枚举吗???????

呵呵 这个和枚举的概念还差很多吧 有空 看看enum 吧

我觉得你对枚举了解太少了,枚举是什么?枚举就是一个class,如果是一个class为什么不能携带多个对象?哎。。。希望你好好的了解和运用一下枚举,不要闭门造车。。。

晕 没人说不能携带呀。。。
我咋就闭门造车了呢 呵呵~
我个人理解枚举 意在枚举,枚举毕竟是以常量为主吧?有什么情况下需要你去枚举变量吗?
元组是类型和变量同事在变化的
所以我很难理解 这两个联系起来 有什么意义
当然你非得说他能当枚举 那肯定的  我定义一个数据 他也能当枚举呀~
22 楼 MrLee23 2013-03-21  
snkcxy 写道
MrLee23 写道
楼主的元组,不就是java中的枚举吗???????

呵呵 这个和枚举的概念还差很多吧 有空 看看enum 吧

我觉得你对枚举了解太少了,枚举是什么?枚举就是一个class,如果是一个class为什么不能携带多个对象?哎。。。希望你好好的了解和运用一下枚举,不要闭门造车。。。
21 楼 MrCrapBag 2013-03-21  
snkcxy 写道
rainsilence 写道
snkcxy 写道
rainsilence 写道
CXY API这个思路不错。。可惜内容是和作者的水平挂钩的。

所以,里面很多文章都有问题。

比如最后一篇,类型判断。

反射是万能的。你说无法判断基本类型

其实Class.isPrimitive方法就可以判断是否是基本类型。

呵呵 本人能力是有限 请多赐教
不过我说的是判断是哪种基本类型,不是判断是否是基本类型 这个有对应方法么?还没细研究过反射的所有方法 请赐教
还有哪些文章有问题 请赐教~

int.class.isPrimitive()

实际上是 我想做的是一个变量i 我想判断他是什么类型的(包括基本类型),而不是您说的是不是基本类型。不要问这有没有意义 之前的讨论说过这个问题。
是什么  和 是不是 是两个概念~
您不用回答是不是 这个不是我文章的内容,请您赐教 如何判断它是什么?


反射得到某个class对象后,比如说classFoo,那么classFoo.getName()就能获取一个类的唯一标识了。

当然,在osgi动态加载的时候,还要和对应加载类的classloader一起才能唯一确定一个类
20 楼 MrCrapBag 2013-03-21  
snkcxy 写道
jjcang 写道
做个返回对象,或者数组就可以了。

嗯 其实元组的方式就是返回对象,只不过类型不是定死的
嗯 数组倒是一种方式 Object[]


java有元组的概念吗?楼主所谓的元组,其实就是对象嵌套对象的做法吧。

顺便说一下,Object[]数组这种方式很不好哦,因为你拿到返回值之后,会做向下造型,这个时候你就要知道原来的类型是什么了,那你还得缓存每个对象的类型,而且在转换的时候,也是不安全的。
19 楼 snkcxy 2013-03-21  
rainsilence 写道
snkcxy 写道
rainsilence 写道
CXY API这个思路不错。。可惜内容是和作者的水平挂钩的。

所以,里面很多文章都有问题。

比如最后一篇,类型判断。

反射是万能的。你说无法判断基本类型

其实Class.isPrimitive方法就可以判断是否是基本类型。

呵呵 本人能力是有限 请多赐教
不过我说的是判断是哪种基本类型,不是判断是否是基本类型 这个有对应方法么?还没细研究过反射的所有方法 请赐教
还有哪些文章有问题 请赐教~

int.class.isPrimitive()

实际上是 我想做的是一个变量i 我想判断他是什么类型的(包括基本类型),而不是您说的是不是基本类型。不要问这有没有意义 之前的讨论说过这个问题。
是什么  和 是不是 是两个概念~
您不用回答是不是 这个不是我文章的内容,请您赐教 如何判断它是什么?
18 楼 snkcxy 2013-03-21  
MrLee23 写道
楼主的元组,不就是java中的枚举吗???????

呵呵 这个和枚举的概念还差很多吧 有空 看看enum 吧
17 楼 snkcxy 2013-03-21  
rainsilence 写道
snkcxy 写道
rainsilence 写道
CXY API这个思路不错。。可惜内容是和作者的水平挂钩的。

所以,里面很多文章都有问题。

比如最后一篇,类型判断。

反射是万能的。你说无法判断基本类型

其实Class.isPrimitive方法就可以判断是否是基本类型。

呵呵 本人能力是有限 请多赐教
不过我说的是判断是哪种基本类型,不是判断是否是基本类型 这个有对应方法么?还没细研究过反射的所有方法 请赐教
还有哪些文章有问题 请赐教~

int.class.isPrimitive()

我晕 大哥 int i=0; 如何判断 i是int 了解么? int.class我的文章里提到过的。
还有 我的文章还哪里有问题您说清楚了呀
16 楼 MrLee23 2013-03-20  
楼主的元组,不就是java中的枚举吗???????
15 楼 rainsilence 2013-03-20  
snkcxy 写道
rainsilence 写道
CXY API这个思路不错。。可惜内容是和作者的水平挂钩的。

所以,里面很多文章都有问题。

比如最后一篇,类型判断。

反射是万能的。你说无法判断基本类型

其实Class.isPrimitive方法就可以判断是否是基本类型。

呵呵 本人能力是有限 请多赐教
不过我说的是判断是哪种基本类型,不是判断是否是基本类型 这个有对应方法么?还没细研究过反射的所有方法 请赐教
还有哪些文章有问题 请赐教~

int.class.isPrimitive()

相关推荐

    Java方法返回多种类型.docx

    Java方法返回多种类型.docxJava方法返回多种类型.docx

    JAVA核心知识点整理.pdf

    Java中的多态性指在一个类实例化时,它可以引用多种不同类型的对象并自动调用适当的方法。这个特征让Java程序员能够更加灵活地编写代码,并且简化了许多任务。 Java中有两种多态性:静态多态性和动态多态性。静态多...

    JAVA上百实例源码以及开源项目

     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知给由recipient参数确定的e-...

    JAVA上百实例源码以及开源项目源代码

     在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被发送给消息发送者,发送一个e-mail通知给由recipient参数确定的e-...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.5.5 重载容易引发误解的两个地方——返回类型和形参名 170 7.5.6 重载中的最难点——参数匹配原则 171 7.6 使用类的实例作为方法参数 172 7.6.1 超车方法:使用类实例做参数 172 7.6.2 调用这个方法 173 ...

    java中关键字Object详解

    其次,Object类是实现Java泛型的基础,Java中的泛型是一种提供给Java程序员们使用的编程技术,它允许程序员们编写出使用一种或多种类型作为参数、返回结果或变量的类、接口以及方法,并且可以在运行时进行类型安全性...

    Java jdbc分页工具类

    java jdbc 分页工具类,以及返回集合数据的封装, private int limit = 10;//每页的个数 /** * 当前页 */ private int page; // /** * 总行数 */ private int totalRows; // /** * 总页数 */ private ...

    Java复习题及答案

    3、所有类至少有一个构造器,构造器用来初始化类的新对象,构造器与类同名,返回类型只能为void。 ( ) 4、包是按照目录、子目录存放的,可以在程序中用package定义包,若没有package一行,则表示该文件中的类不...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    7.5.5 重载容易引发误解的两个地方——返回类型和形参名 170 7.5.6 重载中的最难点——参数匹配原则 171 7.6 使用类的实例作为方法参数 172 7.6.1 超车方法:使用类实例做参数 172 7.6.2 调用这个方法 173 ...

    java开源包11

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包6

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包9

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包101

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包4

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java对Socket进行了封装,可以通过注解调用双端的方法,让socket使用起来极其简单方便,是一个jar包

    所以我对socket进行了封装,客户端和服务端可以通过配置注解,让双方相互调用注解方法,提供了专门的工具类,让注解方法可以支持返回list或map等集合或其他的类型,三行代码你就可以完美的使用socket进行通信,支持...

    java开源包5

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包8

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    200道java面试题资料.pdf

    Java中的多态性指在一个类实例化时,它可以引用多种不同类型的对象并自动调用适当的方法。这个特征让Java程序员能够更加灵活地编写代码,并且简化了许多任务。 Java中有两种多态性:静态多态性和动态多态性。静态多...

    java开源包10

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    实验四 类的构造方法与Java流程控制语句

    构造方法的名称和类同名,没有返回类型。尽管构造方法看起来和一般的成员方法没有差别,但它不是方法,也不是类的成员。因此,构造方法不能直接调用,只能由new 操作符调用。构造方法对于类是十分重要的,对象的初始...

Global site tag (gtag.js) - Google Analytics