James James - 12 days ago 11
Java Question

How to make this if statement true so it does not catch an Exception?

I'm trying to write an if statement that both catches an exception and does not catch an exception, I have caught the exception but I cannot figure out how to make the condition true so that it does not catch the exception and returns the desired value. Here is the code:

Main

package QuestionEditor;

public class Main {
public Main() {
super();
}

public static void main(String[] args) {
Wolf wolfExample = new Wolf();

try {

Food vegFood = new Food("Spinach");
System.out.println("************Wolf Exception example************");
wolfExample.eat(vegFood);
//wolfExample.eat(vegFood);

} catch (Exception e) {
// TODO: Add catch code
e.printStackTrace();
}

System.out.println("************Wolf Non-Exception example************");
Food Meat = new Food("Steak");
System.out.println("Wolves eat " + wolfExample.eat(Meat));
}
}


Animal

package QuestionEditor;

abstract public class Animal
{

String name;
int age;
String noise;

abstract public void makeNoise();

public String getName() {
return name;
}

public void setName(String newName) {
name = newName;
}

abstract public Food eat(Food x) throws Exception;

}

package QuestionEditor;
public class Carnivore extends Animal
{

public Food eat(Food x) throws Exception
{
if (x instanceof Meat) {
return x;
} else {
throw new Exception("Carnivores only eat meat!");
}

}
public String toString(Food x) {
return x.toString();
}

public void makeNoise()
{
noise = null;
}
public String getNoise()
{
return noise;
}
}


Food

package QuestionEditor;

public class Food {

//field that stores the name of the food
public String name;

//constructor that takes the name of the food as an argument
public Food(String name){
this.name = name;
}

public String getName() {
return name;
}
}


Meat

package QuestionEditor;

public class Meat extends Food
{
public Meat(String name) {
super(name);
}

public String getName() {
return super.getName();
}
}


Wolf

package QuestionEditor;

public class Wolf extends Carnivore
{

Wolf()
{
name = "Alex";
age = 4;

}
public void makeNoise()
{
noise = "Woof!";
}
public String getNoise()
{
return noise;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}

public Food eat(Food x) throws Exception
{
if (x instanceof Meat) {
return x;
} else {
throw new Exception("Carnivores only eat meat!");
}
}
}


Output

************Wolf Exception example************
java.lang.Exception: Carnivores only eat meat!
************Wolf Non-Exception example************
at QuestionEditor.Wolf.eat(Wolf.java:34)
at QuestionEditor.Main.main(Main.java:15)
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - unreported exception java.lang.Exception; must be caught or declared to be thrown
at QuestionEditor.Main.main(Main.java:25)
C:\Users\lee-pc\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1


It wants me to catch Meat as an exception but I want to make it so that Meat is not an exception and relates to the Meat condition in the if statement which looks like this:

public Food eat(Food x) throws Exception

{
if (x instanceof Meat) {
return x;
} else {
throw new Exception("Carnivores only eat meat!");
}
}


Should be true of this:

Food Meat = new Food("Steak");
System.out.println("Wolves eat " + wolfExample.eat(Meat));


The desired output would be:

************Wolf Exception example************
java.lang.Exception: Carnivores only eat meat!
************Wolf Non-Exception example************
Wolves eat Meat


I understand that I have made an error but I'm struggling to figure out how to resolve it, any help would be great, thanks.

Answer

The reason why you don't get "Wolves eat Meat" printed, but an Exception is that you still need a try - catch block around every call to .eat() even when you know that the Exception won't be thrown.

The exception you are getting here before the line is printed is a RuntimeException because the code is not compilable

The second reson why this is not working, is that the "meat" you are giving the wolf is of the type Food and not Meat:

Food meat = new Food("Steak");   // no matter what name you give the food, it is still of the class Food

These little changes will make it work:

Food meat = new Meat("Steak");    // you create a Meat object and store it in a Food variable (so to speak)
try{     
    System.out.println("Wolves eat " + wolfExample.eat(meat));   // must be surrounded by a try-catch block
}catch(Exception ex){
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);  // better way to log the exception than ex.printStackTrace();
}

BTW: variables should start with a small letter (Food meat instead of Food Meat .. otherwise how do you know if Meat is the class or your variable? ;)

EDIT another sidenote: your class Food should override the toString() method to be properly printable. Otherwise System.out.println(meat) will just end up in something like com.my.package.Meat@5113de03

Comments