调用构造函数时的NPE

时间:2014-10-07 21:38:23

标签: java selenium pageobjects

我有以下java类(实现页面对象模式)

package core.pageObjects;

import org.openqa.selenium.*;

public class ConsultaClientePorDocumento {

    private WebDriver driver;

    public ConsultaClientePorDocumento(WebDriver d){
        this.driver = d;
    }

    public WebElement cancelarButton = driver.findElement(By.id("Cancelar"));
}

然后我尝试在我的测试中使用它:

import core.pageObjects.*;

ConsultaClientePorDocumento consultaCPD = new ConsultaClientePorDocumento(driver);

我收到以下错误:

java.lang.NullPointerException
at core.pageObjects.ConsultaClientePorDocumento.<init>(ConsultaClientePorDocumento.java:16)

我做错了什么?

2 个答案:

答案 0 :(得分:7)

字段在构造函数体之前初始化(除了对超类构造函数的任何显式或隐式调用之外)。这意味着当driver初始化时,构造函数尚未初始化cancelarButton;它仍然具有默认值null

初始化cancelarButton后,将driver初始化代码放在构造函数中,以确保在driver的初始化代码中需要初始化cancelarButton

private WebDriver driver;

public ConsultaClientePorDocumento(WebDriver d){
    this.driver = d;
    this.cancelarButton = driver.findElement(By.id("Cancelar"));
}

public WebElement cancelarButton;

JLS, Section 12.5指定了此行为:

  

在作为结果返回对新创建的对象的引用之前,处理指示的构造函数以使用以下过程初始化新对象:

     
      
  1. 将构造函数的参数分配给此构造函数调用的新创建的参数变量。

  2.   
  3. 如果此构造函数以同一个类中的另一个构造函数的显式构造函数调用(第8.8.7.1节)开头(使用此方法),则使用这五个相同步骤计算参数并以递归方式处理该构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同;否则,继续步骤5.

  4.   
  5. 此构造函数不以同一类中另一个构造函数的显式构造函数调用开头(使用此方法)。如果此构造函数用于Object以外的类,则此构造函数将以超类构造函数的显式或隐式调用开始(使用super)。使用这五个相同的步骤评估参数并递归处理超类构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同。否则,请继续执行步骤4.

  6.   
  7. 为此类执行实例初始值设定项和实例变量初始值设定项,将实例变量初始值设定项的值按从左到右的顺序分配给相应的实例变量,在这些顺序中它们以文本方式出现在源代码中类。如果执行任何这些初始值设定项导致异常,则不会处理其他初始化程序,并且此过程会突然完成同样的异常。否则,请继续步骤5.

  8.   
  9. 执行此构造函数的其余部分。如果执行突然完成,则此过程突然完成,原因相同。否则,此过程正常完成。

  10.   

我强调了最后一步,即执行构造函数的其余部分。

答案 1 :(得分:3)

您尝试在构造函数设置之前使用driver。将cancelarButton的初始化移动到构造函数中:

public ConsultaClientePorDocumento(WebDriver d){
    this.driver = d;
    cancelarButton = driver.findElement(By.id("Cancelar"));
}

public WebElement cancelarButton;

字段在文件中的位置并不重要,在调用构造函数之前,它们都将被评估。