我想使用泛型在Java中返回不同的类类型,但是有一个错误。
这些返回值具有唯一的字段,因此我不想将其父类用作返回类型。
代码如下:
public class Client {
public static void main(String[] args) {
Client c = new Client();
A a = c.gets(1);
System.out.println(a.aFiled);
B b = c.gets(2);
System.out.println(b.bFiled);
}
public <T extends Root> T gets(int type) {
switch (type) {
case 1:
return new A();
case 2:
return new B();
default:
throw new RuntimeException();
}
}
class Root {
String name;
}
class A extends Root {
int aFiled;
}
class B extends Root {
int bFiled;
}
}
错误发生在switch
“不兼容的类型”
必需:T
找到:Client.A
我的意思是返回某类扩展Root
,但我不知道为什么这是错误的。
如果有人可以向我解释,我将不胜感激。
答案 0 :(得分:4)
在通用方法中,类型由编译器使用实际参数来推断。但是您的参数没有任何类型T。您可以发送另一个参数%(AdditionalDependencies)
来告知返回值的类型:
@Component
public class GarbageCollectorInvoker {
private final Logger logger = LoggerFactory.getLogger(GarbageCollectorInvoker.class);
@Scheduled(cron = "0 0/30 * * * *")
public void execute() {
logger.warn("============GC Status B4=================");
logger.warn("Heap size free (mb): " + Runtime.getRuntime().freeMemory() / 1024 / 1024);
logger.warn("Heap size total (mb): " + Runtime.getRuntime().totalMemory() / 1024 / 1024);
logger.warn("Heap size max (mb): " + Runtime.getRuntime().maxMemory() / 1024 / 1024);
System.gc();
logger.warn("============GC Status After=================");
logger.warn("Heap size free (mb): " + Runtime.getRuntime().freeMemory() / 1024 / 1024);
}
}
但是在您这种情况下,调用此方法之前您不知道类型。
因此,您所能做的就是将此方法设为非泛型,并将返回类型更改为Class<T>
。然后,您可以进行public <T extends Root> T gets(int type, Class<T> c) {
switch (type) {
case 1:
return c.cast(new A());
case 2:
return c.cast(new B());
default:
throw new RuntimeException();
}
}
检查以识别类,执行强制转换,然后获取相关字段。
无论如何都使该方法通用是没有意义的,因为通用方法可以处理不同类型的提供的数据。但在您的情况下,它始终是Root
。所以我想说你的方法不是真正的泛型。
答案 1 :(得分:0)
该方法表明存在一个扩展Root的T,它是返回类型。但是,直到在某处使用该方法之前,您都不知道是哪个类。您不知道T是A,B还是其他。每次使用它都将恰好是Root的一个子类。
但是这里您的代码假设它将同时是A和B。实际上,T可能都不是。如果T是A,则不能返回B的实例。如果T是B,则不能返回A的实例。如果T既不是A也不是B,则不能返回A或B的实例。
您必须返回T的实例。
您可以做的一件事就是不使用泛型,而只返回Root。
答案 2 :(得分:0)
您可以通过强制转换为T来修改以下方法。
public <T extends Root> T gets(int type) {
switch (type) {
case 1:
return (T) new A();
case 2:
return (T) new B();
default:
throw new RuntimeException();
}
}