如何在使用泛型的方法中返回不同的类型?

时间:2019-03-28 03:22:21

标签: java generics

我想使用泛型在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,但我不知道为什么这是错误的。
如果有人可以向我解释,我将不胜感激。

3 个答案:

答案 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();
        }
    }