将 C# 转换为 Java。调用泛型类构造函数的 newInstance() 总是返回 NullPointerException



我对Java相当陌生。我正在尝试从 C# 移植代码,并且在创建泛型类的实例时遇到问题,但我不断收到 NullPointerExceptions。已经有一段时间了,需要另一双更有经验的眼睛。

下面是 C# 版本:

public static T CreateInstance<T>(WebdriverContext context) where T : WebSiteControl
{
//If type has constructor with 1 parameter and is type IContext. Then use that.
//Else use default constructor.
var type = typeof(T);
//First constructor attempt.
var ctor = type.GetConstructor(new[] { context.GetType() });
if (ctor != null)
{
var ctrl = (T)ctor.Invoke(new object[] { context });
return ctrl;
}
//Second constructor attempt.
ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor != null)
{
var ctrl = (T)ctor.Invoke(new object[] { });
ctrl.WebContext = context;
return ctrl;
}
throw new Exception("No appropriate constructors found for " + type.Name);
}

这按预期工作。 Java版本如下:

public static <T extends WebSiteControl> T CreateInstance (Class<T> clazzType, WebdriverContext context) throws Exception{
//If type has constructor with 1 parameter and is type IContext. Then use that.
//Else use default constructor.
Constructor ctor = clazzType.getSuperclass().getConstructor(new Class[] {context.getClass()});
//First constructor attempt.
if (ctor != null)
{            
T ctrl = (T)ctor.newInstance(new Object[] {context});
return ctrl;
}
//Second constructor attempt.
ctor = clazzType.getSuperclass().getConstructor(ctor.getClass());
if (ctor != null)
{
T ctrl = (T) ctor.newInstance(new Object[] { });
ctrl.WebContext = context;
return ctrl;
}      
throw new Exception("No appropriate constructors found for " + clazzType.toString()+".");
}

这一切正常,直到我到达生产线

T ctrl = (T)ctor.newInstance(new Object[] {context});

每当我尝试以任何形式使用 newInstance(( 时,它都会抛出 NullPointerException。 错误消息.img

我觉得我错过了一些非常明显的东西。 有人知道我错过了什么吗?

由于NullPointerException被包装在一个InvocationTargetException中,根据 Oracle Docs,实际的源代码必须位于调用的构造函数中的某个地方:

抛出:InvocationTargetException - 如果底层构造函数引发异常。

您发布的代码似乎很好。

不相关的细节:如果未找到方法,getConstructor()不会返回 null,而是引发异常,因此您的第二次尝试将永远不会到达。

修复了它! @MDK给了我查看其他类初始化的想法。事实证明,在网站控制中,我正在初始化时设置一个变量,该变量依赖于另一个仅在构造函数中设置的变量。

private WebdriverContext Webcontext;
private Webdriver driver = Webcontext.getDriver();
public WebSiteControl(WebdriverContext context){
WebContext = context;
webdriver = WebContext.getDriver();
}

我将我的逻辑与 C# 混合在一起,您可以在其中使用 {get, 私有集} 创建一个变量。

通过将 webdriver = WebContext.getDriver((; 添加到每个构造函数(不理想,但嘿(并且不先初始化驱动程序来修复:

private WebdriverContext Webcontext;
private Webdriver driver;
public WebSiteControl(WebdriverContext context){
WebContext = context;
webdriver = WebContext.getDriver();
}

最新更新