当前位置: 首页 > 知识库问答 >
问题:

带有泛型返回类型的Java方法

章涵蓄
2023-03-14

Java中是否有一种方法可以通过一个方法的声明返回不同的类型?

public Object loadSerialized(String path) {
    Object tmpObject;

    try {
        FileInputStream fis = new FileInputStream(path);
        ObjectInputStream ois = new ObjectInputStream(fis);
        tmpObject = (Object) ois.readObject();

        ois.close();
        fis.close();

        return tmpObject;
    } catch (FileNotFoundException e) {
        return null;
    } catch (Exception e) {
    }
}

我希望此方法返回一个对象,并在函数调用时将其转换为正确的类型。这就是我的想法,但它不是这样工作的。我是否需要某种通用返回类型来执行此操作?解决这个问题的最佳方法是什么?

共有2个答案

赵镜
2023-03-14

您可以在返回类型中使用泛型。它可能看起来像这样。简单地说,编译器根据调用方法的方式为T选择最佳类型。然后,强制转换发生在方法内部,而不是外部。

注意,我使用了try-with-resources语法,以避免结束流带来的混乱。

public <T> T loadSerialized(String path) throws IOException, ClassNotFoundException {
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
        return (T) ois.readObject();
    }
}
姜运珧
2023-03-14

若要安全地执行此操作,需要将所需类型作为 Class 对象传入:

public <T> T loadSerialized(String path, Class<T> targetType) {
    try (ObjectInputStream ois = new ObjectInputStream(
        new BufferedInputStream(
            new FileInputStream(path)))) {

        Object tmpObject = (Object) ois.readObject();
        return targetType.cast(tmpObject);
    } catch (FileNotFoundException e) {
        return null;
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

而您可以编写<code>并返回(T)tmpoobject,这将生成一个编译器警告,因为它不安全:因为编译器只知道T可能是对象(或对象本身)的后代,所以编译器生成<code>(对象),与什么都不做一样。代码盲目地假设返回的对象是T类型,但如果不是,当程序尝试调用T中定义的方法时,您将得到一个意外的异常。最好在反序列化对象后立即知道它是否是您期望的类型。

如果你在列表上进行不安全的施法,也会发生类似的事情:

List<Integer> numbers = Arrays.asList(1, 2, 3);

List<?> list = numbers;
List<String> names = (List<String>) list;  // Unsafe!

String name = names.get(0);    // ClassCastException - not really a String!
 类似资料:
  • 问题内容: 背景 我曾经写过这种方法: 应该这样称呼它: 这很好用(尽管我在研究当前容易出错的问题时在这里的答案中已经看到)。 目前的情况 无论如何,现在我正在编写以下代码(在扩展javax.servlet.jsp.tagext.TagSupport的类中): 目的是可以这样称呼: 我的评估方法中的代码显然不起作用。的第二个参数应该是Class对象。这导致我: 我的问题 如何获得通用(返回)类型的

  • 我在我的Java程序中写了这个函数: 这就是我所说的: 它是有效的,但我觉得我应该能够省略第一个参数,并从返回类型(结果被分配到的类型)推断出它。这可能吗?如果是,语法是什么?

  • 我有一个问题,从抽象类中重写泛型方法。 这是我的抽象类: 当我创建类(B)来实现类(a)时,如下所示: 显示了(getData)方法中的以下编译错误: ”“B。getData“(“字符串函数(字符串)”不是“a”的有效重写。getData'('字符串函数(类型)‘)。dart(无效覆盖) 以及返回语句中的此错误: 类型为“String”的值不能从方法'getData'返回,因为它的返回类型为'St

  • 我试图创建一个Java方法,它接受一个对象类型和它应该转换成的数据类型。 例如,如果我应该能够返回一个值1作为Int或双根据需要。我使用类传递数据类型作为参数。 问题:如何使方法泛型以接受基于输入参数的返回类型? 下面的代码只是一个示例,它可能在语法上不正确,用于解释我的问题。

  • 现在我希望以泛型的方式使用这些类。 如何从方法“method1”和“method2”返回泛型类型(可以是猫或狗)。我有几个返回“T extends Animal”的方法,所以最好在方法级别或类级别中声明泛型类型。

  • 我想让一个函数返回一个保证实现两个接口的对象。编译时不一定知道确切的对象。我的代码看起来像: 在尝试编译时,我遇到以下错误: 你好世界java:13:错误:不兼容的类型:C无法转换为T 返回新的C() ^ 其中T是一个类型变量: T扩展了方法f(布尔值) HelloWorld中声明的a,B。java:14:错误:不兼容的类型:D无法转换为T 返回新的D() ^ 其中T是一个类型变量: T扩展了方法