主类调用其他类方法时如何消除NullPointerException?
解决主类调用其他类方法时的NullPointerException问题
你碰到的这个空指针异常其实是个很典型的对象未初始化问题,咱们一步步拆解:
问题根源
你在Demo类的main方法里确实初始化了WebDriver driver = new ChromeDriver();,但这个driver是局部变量,和Demo类的成员变量、以及Demo_Methods类里声明的public WebDriver driver;都不是同一个对象。Demo_Methods里的driver只是声明了变量,从来没被赋值,默认就是null——当addCountryName()方法里调用driver.findElements()时,自然就抛出NullPointerException了。
修复方案(推荐构造方法传参)
最规范的做法是给Demo_Methods添加一个接收WebDriver实例的构造方法,在创建Demo_Methods对象时把已经初始化好的driver传递进去,这样它内部的driver就不再是null了。
第一步:修改Demo_Methods类
添加构造方法,并确保内部的driver被正确赋值:
public class Demo_Methods { public WebDriver driver; public List<String> Countries = new ArrayList<String>(); public List<String> TotalCases = new ArrayList<String>(); public List<String> NewCases = new ArrayList<String>(); public List<String> TotalDeaths = new ArrayList<String>(); // 新增构造方法,接收外部传入的WebDriver实例 public Demo_Methods(WebDriver driver) { this.driver = driver; } public void addCountryName() throws InterruptedException { // 原方法逻辑保持不变,现在driver已经是可用的实例了 for(int z=1;z<12;z++) { List<WebElement> CountryName = driver.findElements(By.xpath("//table[@id='main_table_countries_today']//tbody[1]//tr["+z+"]//td")); Thread.sleep(5000); for(int x=2;x<6;x++) { if(CountryName.get(1).getText().isEmpty()) { break; } else { WebElement Country=driver.findElement(By.xpath("//table[@id='main_table_countries_today']//tbody[1]//tr["+x+"]//td[2]")); if(Country.getText().isEmpty()) { Countries.add("000"); break; } else { Countries.add(Country.getText()); } WebElement TotalCase =driver.findElement(By.xpath("//table[@id='main_table_countries_today']//tbody[1]//tr["+x+"]//td[3]")); if(TotalCase.getText().isEmpty()) { TotalCases.add("000"); break; } else { TotalCases.add(TotalCase.getText()); } } WebElement NewCase =driver.findElement(By.xpath("//table[@id='main_table_countries_today']//tbody[1]//tr["+x+"]//td[4]")); if(NewCase.getText().isEmpty()) { NewCases.add("000"); break; } else { NewCases.add(NewCase.getText()); } WebElement TotalDeath =driver.findElement(By.xpath("//table[@id='main_table_countries_today']//tbody[1]//tr["+x+"]//td[5]")); if(TotalDeath.getText().isEmpty()) { TotalDeaths.add("000"); break; } else { TotalDeaths.add(TotalDeath.getText()); } } } } }
第二步:修改Demo类的main方法
创建Demo_Methods实例时,把初始化好的driver传进去:
public class Demo { WebDriver driver; int x; public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.chrome.driver", "D:\\Software\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS); driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS); String Url = "https://www.worldometers.info/coronavirus/#countries"; driver.get(Url); Thread.sleep(5000); // 这里传入已经初始化好的driver Demo_Methods DM = new Demo_Methods(driver); DM.addCountryName(); System.out.println(DM.Countries); } }
可选方案:Setter方法传参
如果你不想用构造方法,也可以给Demo_Methods添加一个setDriver方法,在创建实例后手动设置driver:
// 在Demo_Methods类中添加 public void setDriver(WebDriver driver) { this.driver = driver; }
然后在Demo的main方法里:
Demo_Methods DM = new Demo_Methods(); DM.setDriver(driver); // 先设置driver DM.addCountryName();
额外小提示
你的代码里XPath重复写了很多次,建议把公共部分提取成常量,比如:
private static final String BASE_TABLE_XPATH = "//table[@id='main_table_countries_today']//tbody[1]//tr";
这样后续修改XPath只需要改一处,也更易读。另外嵌套循环的逻辑可以再梳理下,避免不必要的元素重复查找,不过这不是导致空指针的原因,先解决核心问题再说~
内容的提问来源于stack exchange,提问作者abhishek agarwal
相关产品推荐
相关产品推荐

