繁体   English   中英

如何调用正确返回泛型类型的方法(Java)?

[英]How to call a method returning generic type correctly (Java)?

我有一个泛型方法,它具有要返回的泛型类型。 我想正确调用它以返回编译错误,以防我使用它的返回类型不符合边界,从而避免运行时错误(与编译)并使用 Java 泛型类型的所有功能。

public <T extends IDeserializable> T restoreObject(byte[] objectArray) {

    T object = T.getDeserialized(objectArray);
    
    return object;
}

然而,这样称呼它

File ret = restoreObject(new byte[] {1,2,3});

不会产生编译错误,因此只会在运行时产生错误。 File 类型没有实现 IDeserializable,但是 java 不会产生编译错误。

public interface IDeserializable {
        public static <T> T getDeserialized(byte[] data) {
            return null;
        }
}

这里有几个问题:

  • 对类型参数调用静态方法并不像您认为的那样工作( 是一个关于的问题)。
  • 无论如何, getDeserialized是一个实例方法,而不是静态方法,所以你不能做T.getDeserialized(objectArray)
  • 编译器不能像那样推断T @luk2302 纠正了我 - T将被推断为您将结果分配给的任何类型。

您需要为restoreObject一个类型为T的参数,以便编译器可以推断出T并且您可以调用getDeserialized方法:

public <T extends IDeserializable> T restoreObject(byte[] objectArray, T t) {
    return t.getDeserialized(objectArray);
}

但是,我怀疑您的意思是getDeserialized是一个静态方法。 不幸的是,您不能这样做,因为静态方法不会被覆盖。 但是,您可以使restoreObject带一个Function参数:

public <T extends IDeserializable> T restoreObject(byte[] objectArray, Function<byte[], T> deserialize) {
    return deserialize.apply(objectArray);
}

然后,您可以对deserialize参数使用 lambda 或方法引用。


您也可以使用Serializable ,但@daniu 指出Serializable将在未来一段时间内被删除,这不是一个好主意。 已经有大量的库,因此您不必自己处理序列化/反序列化。 以下是 Java 中序列化的一些替代方案。 如果您不想使用外部库,Java 也有自己的 XML API。

如果你能想象一个理论类型的Weirdo可以做到:

 class Weird extends File implements IDeserializable

进而:

static <T> T getDeserialized(byte[] data) {
        return new Weirdo();
}

或者更简单(因为不能强制转换为类型参数):

 static <T> T getDeserialized(byte[] data) {
      return (T) "";
 }

您可以看到问题出在您的getDeserialized开始时,调用者必须信任您。 但是,如果您认为接口中存在静态方法的原因(它们的主要目的是返回接口的实例),那么您就是在滥用这些方法。 如果没有人可以覆盖它,那么将其static有什么意义? 您可能想要重新考虑您正在尝试做什么。

但无论如何,如果你用一个class替换它 - 你得到一个编译时错误(不过我会让你弄清楚原因):

public static class IDeserializable {

    static <T> T getDeserialized(byte[] data) {
        return ...;
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM