我创建了一个Auto类,它包含一个OptionSet数组类(即Color,Transmission),它连接到一个包含Options数组内部类(即Blue,Red)的OptionSet类。我计划逐行读取文本文件并用它填充Auto对象。但是,我不知道如何使用在读取文件时定义的OptionSet数组创建Auto对象,而不会出现NullPointerException。
根据我的理解,我不应该使用特定的构造函数,因为数组长度将变得不可更改,使得阅读其他大小的文件变得困难。但是使用默认构造函数意味着optionSet和Option对象中的数组未初始化并导致NullPointerErrors。 (我知道arrayList是构建它的另一种选择,我们将使用它;这是一个在构建产品的过程中遇到常见错误的类项目。)有没有解决这个问题的方法,或者别的我我失踪了?
这是我的错误代码:
Exception in thread "main" java.lang.NullPointerException
at model.Automotive.setOptionSetName(Automotive.java:61)
at util.FileInput.readData(FileInput.java:32)
at driver.Driver.main(Driver.java:17)
自动课程:
package model;
import java.io.*;
import java.io.Serializable;
import model.OptionSet;
import model.OptionSet.Option;
import util.FileInput;
public class Automotive implements Serializable{
//variables
private String name;
private static float basePrice;
private OptionSet[] opSet;
//constructor
public Automotive(int size, String n, float price) {
opSet = new OptionSet[size];
name = n;
basePrice = price;
for(int i=0; i<opSet.length; i++) {
opSet[i] = new OptionSet();
}
}
public Automotive() {
}
public void createOptionsSet(int opSetSize) {
this.opSet = new OptionSet[opSetSize];
}
public void createOption(int opSetLocation, int size) {
this.opSet[opSetLocation].createOption(size);
}
public void setName(String newName) {
name = newName;
}
public String getName() {
return name;
}
public void setPrice(float price) {
basePrice = price;
}
public float getPrice() {
return basePrice;
}
public OptionSet getOptionSet(int location) {
return opSet[location];
}
public void setOptionSetName(int opSetLocation, String opSetName) {
this.opSet[opSetLocation].setOptionSetName(opSetName);
}
public String getOptionSetName(int opSetLocation) {
return this.opSet[opSetLocation].getOptionSetName();
}
public void setOption(int opSetLocation, int opLocation, String name, float price) {
this.opSet[opSetLocation].setOption(opLocation, name, price);
}
public Option getOption(int opSetLocation, int opLocation) {
return this.opSet[opSetLocation].getOption(opLocation);
}
}
optionSet类(带内部类Option)
package model;
import java.io.Serializable;
import java.util.Arrays;
import model.OptionSet;
public class OptionSet implements Serializable{
//variables
private OptionSet[] opSet;
private Option opt[];
private String name;
//constructor
protected OptionSet(String n, int size) {
opt = new Option[size];
name = n;
for(int i=0; i<opt.length; i++) {
opt[i] = new Option();
}
}
public OptionSet() {
}
//methods
protected void createOptionsSet(int size) {
OptionSet[] opSet = new OptionSet[size];//creates OptionSet array
}
protected void createOption(int size) {
this.opt = new Option[size];
}
protected void setOptionSetName(String newNname) {
name = newNname; //to name the optionSet cells - color, transmission, etc
}
protected String getOptionSetName() {
return name;
}
protected void setOption(int location, String newName, float newPrice) {
this.opt[location].setName(newName);
this.opt[location].setPrice(newPrice);
}
protected Option getOption(int location) {
return this.opt[location];
}
protected void setOptionName(int location, String newName) {
this.opt[location].setName(newName);
}
protected String getOptionName(int location) {
return this.opt[location].name;
}
protected void setOptionPrice(int location, float newPrice) {
this.opt[location].setPrice(newPrice);
}
protected float getOptionPrice(int location) {
return this.opt[location].price;
}
protected void deleteOption(int location) {
this.opt[location].deleteOption();
}
protected void deleteOptionName(int location) {
this.opt[location].deleteName();
}
protected void deleteOptionPrice(int location) {
this.opt[location].deletePrice();
}
//does this work to print a custom object?
protected void print(Automotive auto) {
System.out.printf("%10s", name);
for(int j=0; j<opt.length; j++) {
this.opt[j].print(auto);
}
}
//inner class Option
protected class Option implements Serializable{
private String name;
private float price;
Option(String name, float price){
name = name;
price = price;
}
public Option() {
}
protected void print(Automotive auto) {
System.out.printf("%10s", name);
System.out.printf("%10f", price);
}
protected void createOption(String name, float price) {
Option opt = new Option(name, price);
}
protected void setName(String newName) {
name = newName;
}
protected String getName() {
return name;
}
protected void setPrice(float newPrice) {
price = newPrice;
}
protected float getPrice() {
return price;
}
protected void updateName(String newName) {
name = newName;
}
protected void updatePrice(float newPrice) {
price = newPrice;
}
}
FileInput类,使用公共自动方法:
package util;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.StringTokenizer;
import model.*;
public class FileInput {
public Automotive readData(String fileName){
//houses parser
Automotive auto = new Automotive();
// auto.createOptionsSet(5);
try {
FileReader file = new FileReader(fileName);
BufferedReader buff = new BufferedReader(file);
String name = buff.readLine(); //Focus Wagon ZTW
auto.setName(name);
String price = buff.readLine(); //18445
auto.setPrice(Integer.parseInt(price));
int opSetSize = Integer.parseInt(buff.readLine()); //5
auto.createOptionsSet(opSetSize); //create optionSet of size 5
for(int opSetLocation=0; opSetLocation < opSetSize; opSetLocation++) {
String optionTitle = buff.readLine(); //Color
auto.setOptionSetName(opSetLocation, optionTitle);
int opSize = Integer.parseInt(buff.readLine()); //10
//optionsettotal, in each option set option array of size blah
auto.createOption(opSetLocation, opSize);
for (int opLocation=0; opLocation < opSize; opLocation++) { //loop to parse colors
String optionLine = buff.readLine(); //get first color, "gold, 0"
StringTokenizer st = new StringTokenizer(optionLine, ", ");
String optionName = st.nextToken();
float optionPrice = Float.parseFloat(st.nextToken());
auto.setOption(opSetLocation, opLocation, optionName, optionPrice);
}
}
buff.close();
}
catch (IOException e) {
System.out.println("Error -- " + e.toString());
}
return auto;
}
public void serializeAuto(Automotive auto)
{
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("auto.ser"));
out.writeObject(auto);
out.flush();
out.close();
} catch (IOException e) {
System.out.print("Error: " + e);
System.exit(1);
}
}
public Automotive deserializeAuto(String fileName) {
Automotive newAuto = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
newAuto = (Automotive) in.readObject();
}
catch(IOException e) {
System.out.print("Error: " + e);
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return newAuto;
}
}
用于运行实际程序的Driver类:
package driver;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import model.Automotive;
import util.FileInput;
public class Driver{
public static void main(String[] args) {
//Build Automotive object from a file
FileInput file = new FileInput();
Automotive FordZTW = file.readData("C:\\Users\\~ Adam ~\\Documents\\Computer Programming Notes\\Advanced Problem Solving\\FordZTW.txt");
//print attributes before serialization
FordZTW.printAuto(FordZTW);
//Serialize object
file.serializeAuto(FordZTW);
//Deserialize the object and read it into memory
Automotive newFordZTW = file.deserializeAuto("auto.ser");
//print new attributes
newFordZTW.printAuto(FordZTW);
}
}