gpt4 book ai didi

java - 当无法泛化时,正确转换为作为参数传递的未知类型

转载 作者:行者123 更新时间:2023-12-02 12:37:00 25 4
gpt4 key购买 nike

我有一种特殊类型的枚举,它定义了一个类,然后该类可以直接从枚举值实例化。为了实现这一点,每个枚举都实现以下接口(interface):

public interface IEnumWithClass {
public Class<?> getAssociatedClass();
}

一个枚举将如下所示:

public enum Foo implements IEnumWithClass {

eEnumValue(Goo.class);

private final Class<?> mAssociatedClass;

Foo(Class<?> iAssociatedClass) {
mAssociatedClass = iAssociatedClass;
}

@Override
public Class<?> getAssociatedClass() {
return mAssociatedClass;
}
}

然后可以使用以下帮助器实例化该类:

public class EnumWithClassHelper extends EnumWithValueHelper {
private static Object getInstance(Class<?> type) throws Exception
{
Constructor<?> constructor = type.getConstructor();
return constructor.newInstance();
}
}

以及如下所示的调用:

Goo myGoo = (Goo) EnumWithClassHelper.getInstance( Foo.eEnumValue.getAssociatedClass() );

问题:我想避免这里的强制转换,直接得到一个 Goo。

我使用以下助手完成了它:

@SuppressWarnings("unchecked")
private static <T> T getInstance(Class<?> type) throws Exception
{
Constructor<?> constructor = type.getConstructor();
return (T) constructor.newInstance();
}

但在这种情况下,我有一个未经检查的强制转换异常警告,我也不想要它。

有什么方法可以安全地做到这一点,还是我坚持第一个解决方案?由于接口(interface)和枚举限制,我似乎无法将 Class 作为参数传递(我没有成功为枚举指定通用参数)。

谢谢! :)

最佳答案

不幸的是,由于反射不附带任何编译时类型检查,因此您有时需要进行未经检查的强制转换。这又回到了类型转换的基础;在执行代码之前,JVM 不知道将在代码中实例化的对象的类型(根据设计),因此,无法确定适当的类型可用,因此未经检查的强制转换将保持未经检查的状态由于您在界面中使用的泛型。同时,如果您打算使用您正在反射实例化的对象,则没有理由不对其进行强制转换,并且我质疑为什么您不希望进行类型转换,因为所做的只是确保您拥有的变量实际上是它声称的类型只会让你的错误变得更容易。

这个答案可能并不令人满意,所以让我推荐另一个模型供您使用:

public interface IEnumWithClass<T> {
public Class<T> getAssociatedClass();
}

public abstract class Foo<T> implements IEnumWithClass<T> {
// Put any other code that shouldn't be instance-specific here
}

public final class ActualFoos{
public static final Foo<Goo> goo = new Foo<Goo>() {
@Override
public Class<String> getAssociatedClass() {
return Goo.class;
}
};
public static final Foo<Integer> integer = new Foo<Integer>() {
@Override
public Class<Integer> getAssociatedClass() {
return Integer.class;
}
};
}

除此之外,您的 getInstance 方法也可以重新定义:

public static <T> T getInstance(Class<T> type) throws Exception
{
Constructor<T> c = type.getConstructor();
c.setAccessible(true);
return c.newInstance();
}

这允许您使用(例如)ActualFoos.goo.getAssociatedClass() 作为参数调用 getInstance 并直接获取 Goo没有任何强制转换或未经检查的强制转换的对象。因此,例如,如果我们假设方法 getInstance 是类 Bar 的一部分,则代码可能如下所示:

Goo g = Bar.getInstance(ActualFoos.goo.getAssociatedClass());

或者,如果您只引用您知道可以访问的构造函数(可能是公共(public)的),则可以完全放弃辅助方法:

Goo g = ActualFoos.goo.getAssociatedClass().getConstructor().newInstance();

TLDR; 有一种方法可以使用不同的系统完成您想要的操作,但不能完全使用您的系统完成您想要的操作。

关于java - 当无法泛化时,正确转换为作为参数传递的未知类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45110100/

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