提问者:小点点

如何使用构造函数设置其他不在构造函数内部的字段


我在猜测电影游戏,其中我从文本文件中获取电影列表。我有两个类Game用于获取随机电影和Main用于游戏的其余部分。现在我想通过更改Game中的文本文件来添加好莱坞或宝莱坞电影的选择。我分别将'h'或'b'作为输入。我调用Game的构造函数,并使用参数相应地选择文件,但它不起作用,并且始终文件为null并显示NullPointerException

此图像显示了调试期间发生的事情。它跳过setMovieList和构造函数并进入下一行

编辑:我是OOPs的新手,所以请耐心等待。我刚刚在调试过程中看到调试器首先进入类字段,然后进入构造函数,我实际上是在尝试使用file(在构造函数内部)来初始化其他字段,因为它的值是null并且显示NullPointerException

现在我的问题仍然是如何使用filenoOfMovies来初始化Game中的其他字段。

              //showing the setter method that i tried
//Main class
/*only showing the part having Game class*/

//making an object of Game class to get a random movie from the file
    System.out.println("Enter 'h' for hollywood and 'b' for bollywood ");
    Scanner input = new Scanner(System.in);
    char genre = input.next().charAt(0);
    Game newGame = new Game(genre);


//Game class
public class Game
{

    public Game(char genre)
    {
        setMovieList(genre);
    }
    File file;
    int noOfMovies;

    public void setMovieList(char genre)
    {
        if(genre == 'h')
        {
            this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\hollywoodMovies.txt");
            this.noOfMovies = 30;
        }
        else if(genre == 'b')
        {
            this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\bollywoodMovies.txt");
            this.noOfMovies = 20;
        }

    // EDIT ------> I want to initialize the below fields <-------

        private Scanner scan = new Scanner(this.file);

        private int lineCount = 0;
        int random = (int)(Math.random()*noOfMovies)+1;

        //array for storing the movie titles
        private String[] movieArray = new String[noOfMovies];


    }





共2个答案

匿名用户

我不确定…也许你想得到这样的结果:

游戏类

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Game {

    private File file = null;
    //private int noOfMovies = 0;
    private List<String> movies= null;
    FileInputStream read = null;

public Game(char genre) {
     movies = getMovieList();
     System.out.println(movies);
}

public void setMovieList(char genre) {
    if (genre == 'h') {
        this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\hollywoodMovies.txt");
      //  this.noOfMovies = 30;
    } else if (genre == 'b') {
        this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\bollywoodMovies.txt");
      //  this.noOfMovies = 20;
    }

}

public List<String> getList() {
    List<String> movieList = new ArrayList<>();
    String[] values = null;
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String line;
        while ((line = br.readLine()) != null) {
            values = line.split(";");
            movieList.add(values[0]);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return movieList;
}

public String getMovie(){
    System.out.println(movies.size());
    int min = 1;
    int max = movies.size();
    int random = min + (int) (Math.random() * (max - min));

    System.out.println(random);
    String title = movies.get(random);
    return title;
 }

}

主课

import java.util.Scanner;

public class Main {

  public static void main(String[] args) {

    System.out.println("Enter 'h' for hollywood and 'b' for bollywood ");
    Scanner input = new Scanner(System.in);
    char genre = input.next().charAt(0);
    Game newGame = new Game(genre);

    String randomMovie = newGame.getMovie();
    System.out.println(randomMovie);
 }
}

请注意,我已经使用列表数据结构代替数组,但这显然取决于您…让我知道这是否看起来像您正在尝试做的…当然可以进行其他一些改进,但应该可以。

它还假设您有一个txt文件,其中电影标题用分号分隔…否则您必须调整getList中的拆分方法…

此外,通过这种方式,您不再需要noOfMovies字段,因为它会自动获取列表大小。

希望有帮助…

匿名用户

问题是字段在调用构造函数之前被初始化。

有一些事情你应该做:

>

  • 不要从构造函数中调用getter和setter。看到这个问题:我应该在构造函数中使用getter和setter吗?

    如果您正在执行复杂的初始化逻辑,请在构造函数中全部执行。仅使用非常基本的值(而不是依赖于其他字段的值)直接初始化字段。在您的情况下,仅在构造函数中执行所有操作会更容易。这避免了您更改代码以修改构造函数中的值并且某些字段初始化停止工作的问题。