从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

假设我有一个java基类:

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);