gpt4 book ai didi

java - 如何在 Java 中实例化泛型方法参数的实例?

转载 作者:行者123 更新时间:2023-12-02 12:27:45 24 4
gpt4 key购买 nike

考虑以下代码:

// ...
public class BaseClass
{
public BaseClass (int theParam)
{
// ...whatever...
}
}
public class DerivedType
{
// ...Content does not matter...
}


// ...elsewhere:

public <ElemType extends BaseClass> boolean doIt (ArrayList<ElemType> target)
{
ElemType newElem=new ElemType (5) ; // "Cannot instantiate this type"

// ...other code does not matter...

return true ;
}

// ..

如何在 doIt 中创建 ElemType 类型的实例?

显示的构造产生指示的错误。

ElemType.newInstance 不存在,这让我感到惊讶。

我几乎阅读了所有常见问题解答、答案和可通过 Google 搜索到的 Material ,但找不到任何有用的内容。

编辑:是的,我知道反射有其缺点,并且出于多种原因,它并不是最终的解决方案。问题不是“我应该做什么”,而是“我会怎么做”。

最佳答案

如上所述,泛型类型的类型删除不允许这样做。但你可以像这样实现你想要的:

public class BaseClass {

public BaseClass(int theParam) {
// ...whatever...
}
public BaseClass() {
}
}

public class DerivedType extends BaseClass {
}

现在 doIt() 方法获取类参数以供引用:

public <D extends BaseClass> boolean doIt (ArrayList<D> target, Class<D> c)
{
try {
D newElem = c.getDeclaredConstructor(int.class).newInstance(5);
} catch (Exception e) {}

// ...other code does not matter...

return true ;
}

你应该这样调用它:

    ArrayList<DerivedType> testList = new ArrayList<DerivedType>();
testList.add(new DerivedType());
testList.add(new DerivedType());
doIt(testList, DerivedType.class);

希望有帮助:)

请注意,人们可能真的想搞点技巧,摆脱类参数并尝试以下操作:

 public static <D extends BaseClass> boolean doIt (ArrayList<D> target)
{
try {
D newElem1 = ((Class<D>) ((ParameterizedType) target.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getDeclaredConstructor(int.class).newInstance(5);

} catch (Exception e) { e.printStackTrace();}

return true ;
}
}

事实上,我在第二次编辑之前也是这么想的:)但这会得到一个“java.lang.ClassCastException:sun.reflect.generics.reflectiveObjects.TypeVariableImpl无法转换为java.lang.Class “正如您提到的异常(由于忽略了 catch 语句,我没有看到它)。简而言之,Java 运行时系统不存储参数化类型(有利于向后兼容;因此将来可能会改变)。

所以,看起来如果不“接触”某些类就不可能实现。

但是,除了提到的方法之外,我还可以想到另外两件事。首先,如果 BaseClass 和 DerivedType 'D' 类都实现了 clone() 方法,则可以从数组中获取对象的克隆,然后使用它:

         D o = target.get(0);

D oNew = (D)((BaseClass)o).clone();
target.add(oNew);

多态性将处理剩下的事情:)

第二个不是真正的“解决方案”,但如果您想要的只是按类型参数化的对象数组的新实例,则可以使用第二个。类型删除仅发生在参数化类型上,但不会发生在基本数组上(数组在 JVM 中是具体化的)。因此,如果我们可以自由地更改方法的签名并且可以使用数组,那么以下内容将起作用:

    public <D extends BaseClass> boolean doIt(D[] target) {
try {
D newD = (D) (target.getClass().getComponentType().getConstructor(int.class).newInstance(8));
target[0] = newD;

// The following is optional, if we want to work with Collections internally
List<D> l = new ArrayList<D>(Arrays.asList(target));
l.add(newD);


} catch (Exception e) {
e.printStackTrace();
}
return true;
}

注意:如果我们无法引入新参数, super 类型标记将无法解决此问题。如果我错了,请纠正我。

关于java - 如何在 Java 中实例化泛型方法参数的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9689325/

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