0

I'm trying to override a toString method from a parent class but whenever I try to run the program, it throws a NullPointerException even though my constructors are already initialized. The Car class that extends Vehicle is where the problem is. Ehen I remove the spec.getNoOfDoors the program runs.

Here are my classes:

Vehicle:

public abstract class Vehicle {
    private String serialNo;
    private Double price;
    private Integer size;
    VehicleSpec spec;

    public Vehicle(String serialNo, double price, int size, VehicleSpec spec) {
        this.serialNo = serialNo;
        this.price = price;
        this.size = size;
        this.spec = spec;
    }

    ... // getters and setters

    @Override
    public String toString() {
        return String.format("%s - %s, Color: %s - Serial No.: %s - Price: %s - Size: %s - ", spec.getBrand(), spec.getModel(), spec.getColor(), this.serialNo, this.price, this.size);
    }
}

Car:

public class Car extends Vehicle{
    CarSpec spec;

    public Car(CarSpec spec, String serialNo, double price, int size) {
        super(serialNo, price, size, spec);
    }

    @Override
    public String toString() {
        return String.format(super.toString() + "Door: %d", spec.getNoOfDoors()); //<- this is where the problem is..
    }
}

Here is the error:

Exception in thread "main" java.lang.NullPointerException
at com.inventory.main.Car.toString(Car.java:12)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at com.inventory.main.CarInventorySearch.main(CarInventorySearch.java:16)
Keiwan
  • 8,031
  • 5
  • 36
  • 49
Anthony
  • 77
  • 1
  • 10
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – denvercoder9 Nov 12 '16 at 09:17
  • This is a large code dump, and you should at least tell us which line has the problem. – Tim Biegeleisen Nov 12 '16 at 09:18
  • Removed the other codes, the problem is in the Car class, even though I already initialized the noOfDoors in the constructor, it still throws null pointer exception. – Anthony Nov 12 '16 at 09:21
  • @Anthony Post your error logs. In which line does the exception occurs? Did you even go through the link: [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – denvercoder9 Nov 12 '16 at 09:23
  • 1
    Correct me if I'm wrong, but have you actually set the CarSpec spec; variable in the car class? – Sulphate Nov 12 '16 at 09:23
  • @RafiduzzamanSonnet, but this contains a value when I initialized the constructor. – Anthony Nov 12 '16 at 09:23
  • 1
    Maybe you should do this in the Car constructor: `this.spec = spec;` – denvercoder9 Nov 12 '16 at 09:25
  • @RafiduzzamanSonnet, I already did that in the Vehicle class constractor. – Anthony Nov 12 '16 at 09:27
  • Your Car class contains a field named `spec`, which hides the field `spec` in the `Vehicle` class. So you have two fields called `spec` and you have to assign both a value. – dunni Nov 12 '16 at 09:28
  • @Sulphate, yes I have that in the Car class. – Anthony Nov 12 '16 at 09:28
  • @Anthony In the `toString( )` method of `Car` class you are doing `spec.getNoOfDoors( )`. This `spec` is the one defined above the constructor and has never been initialized. It currently refers to `null`. You have to initialize it in the `Car`'s constructor – denvercoder9 Nov 12 '16 at 09:28
  • @dunni, I also have a VehicleSpec class whic is the parent class of CarSpec class. I posted all my classes earlier but I was told that it was a huge code dump so I deleted it. – Anthony Nov 12 '16 at 09:32
  • Doesn't matter in this case. The two spec fields are still different fields. – dunni Nov 12 '16 at 09:33
  • @RafiduzzamanSonnet, but the Car's constructor takes properties from CarSpec's constructor, do you think it would help if I post those classes here so you can see? – Anthony Nov 12 '16 at 09:36
  • @Anthony You might want to follow the link in my answer to clear up the confusion about the fact that you have two different `spec` properties and how **hiding** works in Java. – Keiwan Nov 12 '16 at 09:52
  • @Keiwan, yes, thanks for the link. – Anthony Nov 12 '16 at 12:10
  • @Anthony No problem. I'm glad it helped. – Keiwan Nov 12 '16 at 12:11
  • @Keiwan, I've been studying java for almost 4 weeks now, and I am beginning to realize why most people loves to hate it.. – Anthony Nov 12 '16 at 12:34

2 Answers2

3

I think the misconception is that the

CarSpec spec;

is somehow meant to be same (or override) the

VehicleSpec spec;

which is declared and initialized in the superclass (Vehicle). However, this is not the case.

These are two different properties, of which you will only be able to access the spec of type CarSpec in the subclass. This spec will not be initialized, just because you have initialized the VehicleSpec spec in your superclass.

So you need to initialize this spec in the constructor of the subclass like

this.spec = spec;

Note that this behaviour is hiding and not overriding. Variables, unlike methods, are resolved at compile-time and not at runtime.

Community
  • 1
  • 1
Keiwan
  • 8,031
  • 5
  • 36
  • 49
0

try like this

    public class Car extends Vehicle{
//Below 'spec' is local for Car and not have the reference Vehicle class 'spec'
    CarSpec spec;

    public Car(CarSpec spec, String serialNo, double price, int size) {
        super(serialNo, price, size, spec);
        //Local 'spec' assigned by the spec received from constructor and the same in Vehicle 
        this.spec = spec;
    }

    @Override
    public String toString() {
        return String.format(super.toString() + "Door: %d", spec.getNoOfDoors()); //<- this is where the problem is..
    }
Hemakumar
  • 639
  • 9
  • 24