我的 Java 代码需要一双全新的眼睛

Need a fresh set of eyes with my Java code

我希望社区能为我提供新的视角,因为我已经有点代码盲了,

我已经附上了我必须连接在一起以获得 udemy 教程的两个 classes 的代码。

当我编译它们时,出现了常见的错误,变量拼写错误和分号丢失。它还通过了一个意想不到的类型,通过将 int 更改为 String 解决了这个问题。

我遇到的问题在第 25 行,它给我的错误是

incompatible types, There was an expression of a certain type required here. You provided an expression of a different type hat is not compatible. (e.g. you wrote a String where an int was expected.)

但据我所知,在所有实例中,被调用的变量都被声明为字符串。

我用 intelliJ 编写它并用它来生成 getter/setter 方法,所以这些应该都是正确的,我就是无法在我的生活中看到错误的来源。

我知道这会很简单,但只见树木不见森林。

汽车class.

public class Car
{
   // instance variables
   private int numOfMilesDone; // a car has-a number of miles drive, "20000"
   private int yearBought; // a car has-a year it was bought "1997"
   private int carValue;  // a car has-a value of what it is worth "300"
   private Model modelName; // a car has-an model of type Model

   /**
    * Constructor for objects of class Car
    */

   public Car(int aNumMiles, int aYearBought, int aValue, Model aModelName)
   {
      this.numOfMilesDone = aNumMiles;
      this.yearBought = aYearBought;
      this.carValue = aValue;
      this.modelName = aModelName;
   }

   public Model getModelName()
   {
      if (this.modelName == null || this.getModelName() == null )
      {
         return ("needs to be checked");
      }

      return modelName;
   }

   /**
    * Getter method for number of miles the car has done
    * @return
    */

   public int getNumOfMilesDone()
   {
      return numOfMilesDone;
   }

   /**
    * Setter method for number of miles the car has done
    * @return
    */

   public void setNumOfMilesDone(int numOfMilesDone)
   {
      this.numOfMilesDone = numOfMilesDone;
   }

   /**
    * Getter method for the year the car was bought
    * @return
    */

   public int getYearBought()
   {
      if (this.yearBought == null)
      {
         return "Needs to be checked";
      }

      return yearBought;
   }

   /**
    * Setter method for the year the car was bought
    * @return
    */

   public void setYearBought(int yearBought)
   {
      this.yearBought = yearBought;
   }

   /**
    * Getter method for the year the cars value in pounds
    * @return
    */

   public int getCarValue()
   {
      return carValue;
   }

   /**
    * Setter method for the year the cars value in pounds
    * @return
    */

   public void setCarValue(int carValue) {
      this.carValue = carValue;
   }

   public boolean isClassic()
   {
      return(Integer.parseInt(this.modelName.getYearOfModel()) < 1969);
   }

   /**
    * returns the a String describing the object
    * @return
    */

   public String toSting()
   {
      return this.getModelName() + " has done " + this.numOfMilesDone + ", it is worth " + this.carValue + ", it is " 
              + this.isClassic() + " it's a classic.";
   }

}

我的另一个class,Model,这个编译没问题

public class Model
{
    private String modelName; // the model has a model name
    private String yearOfModel; // the year the model was created


    /**
     * constructor method for no model attributes
     */

    public Model()
    {
        this.modelName = null;
        this.yearOfModel = null;
    }


    /**
     * constructor method for known modelName attribute, but no yearOfModel attribute
     * @param bModelName
     */

    public Model(String bModelName)
    {
        this.modelName = bModelName;
        this.yearOfModel = null;
    }

    /**
     * constructor method for known modelName attribute, and known yearOfModel attribute
     * @param bModelName
     * @param yearOfModel
     */

    public Model(String bModelName, String yearOfModel)
    {
        this.modelName = bModelName;
        this.yearOfModel = yearOfModel;
    }

    /**
     * modelName getter method
     * @return
     */

    public String getModelName() {
        return modelName;
    }

    /**
     * modelName setter method
     * @param modelName
     */

    public void setModelName(String modelName) {
        this.modelName = modelName;
    }

    /**
     * yearOfModel setter method
     * @return
     */

    public String getYearOfModel() {
        return yearOfModel;
    }

    /**
     * yearOfModel setter method
     * @param yearOfModel
     */

    public void setYearOfModel(String yearOfModel) {
        this.yearOfModel = yearOfModel;
    }

    /**
     * returns the modelName and yearOfModel variables as comprehensible information.
     * @return
     */

    public String toString()
    {
        return this.modelName + " was launched in " + this.yearOfModel;
    }
}

在此先感谢您的帮助。

return "Needs to be checked" 当您的方法签名建议的是 ModelName.

时,您将返回一个字符串

您需要更正getYearBought()getModelName()中的两个方法。它们都返回字符串,而 getYearBought() 期望返回一个 int,getModelName() 期望返回一个 Model class 的对象

我能看到的几个问题。您的方法 getModelName() 调用自身 this.getModelName()

return class ModelmodelName 也是 Model 类型。但是在你的 if 语句中你 return 一个字符串而不是 class Model

if (this.modelName == null || this.getModelName() == null ) {
    return ("needs to be checked"); // This needs to return a Model
}

跳出几个错误:

你至少有两处错误:

getModelName() 你有两个问题:

1) 您打算 return a Model 但在错误情况下 return a String

2) 你在没有终止条件的情况下递归调用 getModelName()

 public Model getModelName()
 {
  if (this.modelName == null || this.getModelName() == null )
  {
     // NOTE: This is a String!
     return ("needs to be checked");
  }

  return modelName;
 }

可以这样重写:

public Model getModelName() {
    return modelName;
}

modelName 为空时它将 return 为空,否则为非空 Model

此外,在 getYearBought() 中,您做同样的事情 - return 一个 String 当您打算 return 一个 int

public int getYearBought() { 如果(this.yearBought == null) { // 注意:这个 returns 字符串 return "Needs to be checked"; }

  return yearBought;

}

不需要检查 yearBought 是否为空,这是一个 int,它不能为空。您可以这样重写它:

public int getYearBought() {
    return yearBought;
}

您遇到问题是因为您使用 C like 样式,而 return 值用于检测问题。在这种情况下,您不能使用它,因为 return 类型和字符串错误消息不相同(例如 String.indexOf() return 位置或 -1 如果未找到) .

在你的情况下,最好随消息一起抛出 NullPointerException

public Model getModelName() {
    Objects.requireNonNull(modelName, "needs to be checked");
    return modelName;
}

public int getYearBought() {
    Objects.requireNonNull(yearBought, "Needs to be checked");
    return yearBought;
}

这不是您问题的答案,但我认为您的代码还有其他问题。下面评论几句。

// it's better to check value when set it, but not when get (class instance should always contains correct value, this is plain old dto)
// do hot use useless JavaDoc: make code self documented
class Car {

    private int numOfMilesDone; // a car has-a number of miles drive, "20000"
    private int yearBought; // a car has-a year it was bought "1997"
    private int value;  // a car has-a value of what it is worth "300"
    private final Model model; // a car has-an model of type Model

    // the name of method's parameters and local ones usually the same (use this for local ones)
    public Car(int numOfMilesDone, int yearBought, int value, Model model) {
        setNumOfMilesDone(numOfMilesDone);
        setYearBought(yearBought);
        setValue(value);
        // use null object instead of null
        this.model = model != null ? model : Model.NULL;
    }

    public Model getModel() {
        return model;
    }

    public int getNumOfMilesDone() {
        return numOfMilesDone;
    }

    public void setNumOfMilesDone(int numOfMilesDone) {
        this.numOfMilesDone = Math.max(0, numOfMilesDone);
    }

    public int getYearBought() {
        return yearBought;
    }

    public void setYearBought(int yearBought) {
        this.yearBought = Math.max(0, yearBought);
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return model + " has been done " + numOfMilesDone + ", it is worth " + value + ", it is " + model.isClassic() + " it's a classic.";
    }
}

// you retrieve instance from `Car` class. It is better to make `Model` immutable and do not worry about encapsulation
final class Model {

    public static final Model NULL = new Model(null, null);

    // no need to use `Mode` in the name of internal properties
    private final String name;
    // usually this is integer, not a string
    private final int year;

    public Model(String name) {
        this(name, 0);
    }

    public Model(String name, int year) {
        this.name = name;
        this.year = Math.max(0, year);
    }

    public String getName() {
        return name;
    }

    public int getYear() {
        return year;
    }

    // this method belongs to the Model, but not to a Car
    public boolean isClassic() {
        return this != NULL && year < 1969;
    }

    @Override
    public String toString() {
        return name + " was launched in " + year;
    }
}