gpt4 book ai didi

Java 泛型限制或错误用法?

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:54 26 4
gpt4 key购买 nike

我有一个类表示一对相同类型的两个值(类型可以是一组特定类型中的任何一种):

  public class Pair<E extends AClass>{
private E var1;
private E var2;
}

此类由框架使用,因此它需要一个无参数构造函数,我必须在其中实例化 2 个变量(var1、var2):

  public class Pair<E extends AClass>{
private E var1;
private E var2;

public Pair(){
var1 = invoke constructor of type E;
var2 = invoke constructor of type E
}
}

这里显然有很多问题:

  1. 为了实例化变量,我应该以某种方式知道它的确切类型并调用该特定类型的构造函数;在最好的情况下,这意味着在构造函数中有一个相当大的 if else 语句,例如:

     public Pair(){
    if(var1 instanceof SpecificType1){
    var1 = new SpecificType1();
    var2 = new SpecificType2();
    }
    }
  2. 即使我这样做,我也会遇到一些问题,因为 var1 被声明为 E 类型,并且在尝试实例化 SpecficType1 并将结果对象分配给 var1/var2 时,我会收到类型不匹配错误。为了让它工作,我必须转换为 E :

       var1 = (E)new SpecificType1();

但这破坏了编译时类型检查,因为我试图将特定类型转换为通用类型。

这是 Java 中泛型的限制,还是这种情况不适合使用泛型?

最佳答案

In order to instantiate the variables I should somehow know its exact type and invoke that specific type's constructor; in the best case this means to have a pretty large if else statement in the constructor, something like:

在那之前你会遇到问题。

   if(var1 instanceof SpecificType1){
var1 = new SpecificType1();
var2 = new SpecificType2();
}

var1null在这一点上,所以 var1 instanceof Tfalse对于所有 T .


Java 泛型的一个限制是泛型类型参数是 erased因此,您无法从零参数构造函数中反射(reflect)类型参数。

调用者必须提供一些上下文来告诉您如何初始化 var1var2 ,提供该上下文的典型方法是通过构造函数参数。


你最好的选择可能是让 var1var2出发null然后延迟初始化,直到您可以获得所需的上下文。

也许

void init(Class<E> type) {
if (type.isAssignableFrom(ConcreteType1.class)) {
var1 = type.cast(new ConcreteType1(...));
var2 = type.cast(new ConcreteType1(...));
} else { /* other branches */ }
}

这并不完美,因为您仍然无法区分 E extends List<String>来自 E extends List<Number>但对你的情况来说可能已经足够好了, .cast 方法会给你一个类型安全的转换为 E .


或者,Guava、Guice 和相关库提供类似 Supplier<E> 的东西在 init 中可能会派上用场的界面方法。

关于Java 泛型限制或错误用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12548394/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com