I have a class called Food.java that has two constructors. The driver code I have been given calls its copy constructor inside its constructor with its own object as the parameter. The copy constructor has the parameters food
and flavor
. This is an object is then printed out using a toString()
method but the toString()
method is giving me the food variable and the flavor
variable are both null
. Would anyone be able to tell me why? Thank you.
Driver code:
public static void main(String args[]) {
System.out.println(new Food(new Food("Ice-cream", "Vanilla")));
}
My code :
public class Food {
private String food;
private String flavor;
private Food f;
public Food(String food, String flavor) {
this.food = food;
this.flavor = flavor;
}
public Food(Food f) {
this.f = f;
}
public String toString() {
return food " " flavor;
}
}
Output:
null null
CodePudding user response:
When you call System.out.println (new Food (new Food ("Ice-cream", "Vanilla")));
you are creating to Food instances. When the inner instance is created this constructor is called:
public Food(String food, String flavor) {
this.food = food;
this.flavor = flavor;
}
Here food and flavor are set. Then the outer Food instance is created with the other constructor. Here only f is set, not food and flavor. And the outer instance is thrown into the println, so this is the instance toString is called on. What you want is a constructor doing this:
public Food(Food other) {
this.food = other.food;
this.flavor = other.flavor;
}
And then you can delete the field f.
CodePudding user response:
What's Happening:
The first object creation correctly stores the food and flavour as "Ice-cream" and "Vanilla" but leaves the variable f uninitialized.
The second object creation takes the Food object you just created as input and then stores it in its f variable. food and flavour are left uninitialized.
Therefore, when the printline is called it gets the uninitialized values in food and flavour.
How to Fix it:
Firstly, you can probably remove the f variable as it seems to be redundant - the object itself will already store the information you require. Generally speaking an object will never be a property of itself.
Then, in the second constructor that uses a Food as input you just change the code to use the food and flavour instead.
public Food(Food f) {
this.food = f.food;
this.flavor = f.flavor;
}
CodePudding user response:
public class Food {
private final String food;
private final String flavor;
// you should not add Food f; you have 2 copies of the same object
// copy constructor should check for null and set all parameters
public Food(Food f) {
food = f == null ? null : f.food;
flavor = f == null ? null : f.flavor;
}
public Food(String food, String flavor) {
this.food = food;
this.flavor = flavor;
}
@Override
public String toString() {
return food ' ' flavor;
}
}
CodePudding user response:
You need the .toString() to be called from somewhere. Your driver code should probably look something like this.
public static void main(String[] args){
System.out.println((new Food ("Ice-cream", "Vanilla")).foodToString();
}
foodToString() would be your toString method in your food class unless you override the generic to string method.