从java方法返回不同的类型
假设我有一个java基类:从java方法返回不同的类型,java,generics,generic-programming,Java,Generics,Generic Programming,假设我有一个java基类: class base { public Class<? extends base> type; // ... } 如何实现这样一个函数(container.get),在返回对象之前将对象强制转换为正确的类型? 如果能够以级联方式编程,那就太好了: JSONObject o; //... o.get("nestedObject").get("array").get(3); 我想你指的是泛型 class container<Gener
class base {
public Class<? extends base> type;
// ...
}
如何实现这样一个函数(container.get
),在返回对象之前将对象强制转换为正确的类型?
如果能够以级联方式编程,那就太好了:
JSONObject o;
//...
o.get("nestedObject").get("array").get(3);
我想你指的是泛型
class container<GenericType> {
private Vector<GenericType> v;
//...
public GenericType get(int i){
GenericType b=v.get(i);
return b;
}
}
类容器{
私有向量v;
//...
公共泛型get(int i){
GenericType b=v.get(i);
返回b;
}
}
你不能那样做。泛型并不是这样工作的。在编译时无法知道对象的确切子类型
这b.type.cast(b)代码>强制转换将需要对方法的结果执行public get(int i)
无论在何处调用
如果系统设计得很好,就不需要将对象强制转换回确切的子类
否则,最好在需要时执行instanceof
类型检查
type
存储从基继承的类的类类型
这相当于This.getClass()
我如何实现这样一个函数(container.get),它在返回对象之前将对象强制转换为正确的类型
理论上不可能。在编译和发布代码之后,人们将创建更多的子类并将其放入容器中。这就是创建基类的目的——这样代码库的另一部分只需使用单个接口/概念即可
所以基本上你想写的只是一些通用的容器代码
interface Container<T extends Base> {
public T get(int i);
}
您还可以向Base
添加自定义cast方法。您可能误解了Java中的“cast”是什么。除了涉及基元类型的强制转换(例如将int
强制转换为float
),强制转换根本不会更改对象
实例变量之一是
private Vector<Base> v;
x
(如果不为null)将是Base
或子类的某个对象。x
的类型将是用于构造对象的任何类型。现在如果你说
Child1 y = (Child1)x;
如果x
是Child1
,y
将引用与x
相同的对象。但是编译器会知道y
是Child1
,您可以访问Child1
中定义的新方法。(如果x
不是Child1
,则会出现异常。)但需要注意的是,强制转换不会创建新对象,也不会更改任何对象的类型。它只是告诉编译器以不同的方式查看变量或表达式
有鉴于此,您无法通过尝试编写返回“variable”类型的方法获得任何好处。你还是写吧
public Base get(int i){
return v.get(i);
}
它返回的对象可以是Base
、Child1
、Child2
,等等。;它将与将对象放入向量时的类型相同。当您调用get
时,如果您希望结果是Child1
,您可以说
Child1 child = (Child1)container.get(n);
如果对象不是child1
,则会引发异常。或者您可以使用instanceof
检查您自己:
Base child = container.get(n);
if (child instanceof Child1) {
...
}
如果这还不够好,你需要更清楚地解释你想要完成什么,以及为什么这样做行不通
更多:阅读您的编辑后,表示您希望执行以下操作:
JSONObject o;
//...
o.get("nestedObject").get("array").get(3);
你不需要任何铸造来完成这一点。您需要的是一个抽象的JSONValue
基类型,它表示可以从JSON解析器返回的任何类型的值。子类可以是“object”、“array”以及您需要的任何标量类型(integer、string等)get
将返回JSONValue
。实际上,它将返回一个其他类型的对象,但编译器需要知道的是它返回JSONValue
现在,一个JSONValue
将需要两个get
方法,一个接受String
,另一个接受int
或Integer
。这些将是多态方法。假设v
是一个JSONValue
,你说v.get(“array”)
:根据v
的实际类型,它实际调用的方法可能不同。因此,如果v
是您的“对象”类型,它将调用您为对象类型定义的方法;如果v
是整数类型,它将调用为整数类型定义的方法,依此类推。您需要的是get
方法,该方法使用String
查找字段中的JSON“object”类型,并对其他所有内容抛出异常。类似地,对于采用整数参数的get
方法,JSON“array”类型的方法将查找列表或其他内容,而JSONValue
的每个其他子类的方法将抛出异常。这不需要“铸造”。强制转换是一个编译时概念。在任何时候,编译器都只知道它正在使用JSONValue
。但在运行时,对象的实际类型用于确定调用哪个方法,因此编译器不需要知道更多
这是所有Java程序员都需要知道的一个基本概念(现在还有Javascript、Python和几乎所有其他语言,尽管多态性在Javascript和Python等解释语言中的处理方式不同)。本教程将介绍这一点和相关概念。关于“多态性”可能还有更好的Java教程。你需要从容器返回吗。获取任何从基扩展的类型吗?是的//10个字符如果我理解正确,你可以使用泛型来限制它从基扩展,这是你的意思吗?我尝试了public T get()
,但没有成功,intellij说我需要将返回类型转换为T
。我是java新手,你是这么想的吗
Child1 child = (Child1)container.get(n);
Base child = container.get(n);
if (child instanceof Child1) {
...
}
JSONObject o;
//...
o.get("nestedObject").get("array").get(3);