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

时间:2019-05-06 17:16:18

标签: java oop constructor

我正在猜测一个电影游戏,其中我从文本文件中获取电影列表。我有两个班级,Game用于获取随机电影,Main用于其余的游戏。现在,我想通过更改Game中的文本文件来增加好莱坞或宝莱坞电影的选择。我分别以“ h”或“ b”作为输入。我用参数调用Game的构造函数来选择文件,但是它不起作用,并且文件总是null并显示NullPointerException

This image showing what happens during debugging. It skips the setMovieList and constructor and comes to the next line

编辑:我是OOP的新手,请耐心等待。我刚刚在调试过程中看到,调试器首先进入类字段,然后进入构造函数,实际上,我试图将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 个答案:

答案 0 :(得分:0)

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

您应该做很多事情:

  1. 不要从构造函数中调用getter和setter。看到以下问题:Should I use getters and setters in constructors?

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

答案 1 :(得分:0)

我不确定。.也许您想要得到这样的结果:

游戏类

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中调整split方法。

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

希望有帮助...