调用rentMovie方法租片时触发NullPointerException问题排查
先把你提供的代码片段整理出来(方便定位问题):
public void rentMovie(){ System.out.println("Enter a customer ID: "); int ID = In.nextInt(); System.out.print("Enter a movie: "); String name = In.nextInt(); for(Customer customer: customers){ Optional<Movie> movie = catalogue.getMoviesAvailable().stream() .filter(b -> b.getTitle().equals(movieName)) .findFirst(); if(movie.isPresent()) { catalogue.getMoviesAvailable().remove(movie.get()); catalogue.getMoviesRented().add(movie.get()); customer.getCurrentlyRented().add(movie); customer.getRenti... } } }
下面我会一步步拆解最可能触发空指针异常的点,以及对应的修复方案:
1. In对象未初始化
你代码里用了In.nextInt()读取输入,但如果In是Scanner实例却没有提前初始化(比如没写Scanner In = new Scanner(System.in);),那调用它的方法时直接就会抛出NullPointerException。
解决办法:
在方法开头或者类的初始化逻辑里创建Scanner实例,确保它在调用rentMovie()前处于可用状态:
Scanner In = new Scanner(System.in);
2. 变量名不匹配引发的null值
你定义的电影名称变量是name,但过滤电影时用的是movieName——如果这是笔误,movieName要么未定义,要么是未赋值的null。另外,如果电影的title本身是null,调用b.getTitle().equals(...)也会触发空指针。
解决办法:
统一变量名,同时调整判断顺序避免null风险:
// 用name.equals(...),即使b.getTitle()是null也不会抛异常 .filter(b -> name.equals(b.getTitle()))
或者更严谨的写法:
.filter(b -> b.getTitle() != null && b.getTitle().equals(name))
3. catalogue或内部集合未初始化
如果catalogue本身是null,调用catalogue.getMoviesAvailable()会直接空指针;另外,如果getMoviesAvailable()/getMoviesRented()返回的是null(而不是空集合),后续调用stream()、remove()、add()这些方法都会触发异常。
解决办法:
- 确保
catalogue在使用前已经被实例化(比如通过构造函数注入或者提前new出来)。 - 修改
Catalogue类的方法,让getMoviesAvailable()和getMoviesRented()始终返回空集合而非null,比如在类的构造函数里初始化moviesAvailable = new ArrayList<>();。
4. customers集合为null或包含null元素
如果customers本身是null,增强for循环for(Customer customer: customers)会直接抛空指针;如果集合里有null的Customer对象,调用customer.getCurrentlyRented()时也会触发异常。
解决办法:
- 确保
customers集合在使用前已初始化(比如customers = new ArrayList<>();),哪怕没有客户也要保持集合为空而非null。 - 遍历前先过滤掉null元素:
for(Customer customer : customers) { if(customer == null) { continue; // 跳过无效的null客户 } // 后续业务逻辑 }
5. customer.getCurrentlyRented()返回null
如果Customer类的getCurrentlyRented()方法返回的是null(而非空集合),调用add()方法时会直接空指针。另外你这里直接添加Optional<Movie>对象也是逻辑错误,应该添加movie.get()。
解决办法:
- 修改
Customer类,在构造函数里初始化currentlyRented = new ArrayList<>();,确保getCurrentlyRented()始终返回有效集合。 - 修正添加对象的代码:把
customer.getCurrentlyRented().add(movie);改成customer.getCurrentlyRented().add(movie.get());
额外小问题:用nextInt()读取电影名称
nextInt()只能读取整数,用户输入带字母或空格的电影名称时会抛出InputMismatchException,虽然不是空指针,但也是潜在bug。
解决办法:
改用nextLine()读取,注意处理nextInt()遗留的换行符:
System.out.println("Enter a customer ID: "); int ID = In.nextInt(); In.nextLine(); // 吃掉nextInt()后的换行符 System.out.print("Enter a movie: "); String name = In.nextLine();
内容的提问来源于stack exchange,提问作者user9747634

