I have a function like the following one:
public static double calculateValuationByTransmission(double price, char transmission) { if (transmission == 'A') { return price * 0.05; } else if (transmission == 'M') { return price * -0.05; } else { System.out.println("Transmission must be: 'A' or 'M'"); return 0; } }
As you can see this function shows the an error message when the input parameter transmission
does not receive the expected values. Furthermore, it returns 0. I want to use this function in another function as follows:
public static double calculateValuation(double price, int mileage, int age, char transmission) { if (price < 0.0 || mileage < 0 || age < 0) { System.out.println("Price, mileage and age must be a positive number"); return -1; } //HERE double valueTransmission = PAC1Ex2.calculateValuationByTransmission(price, transmission); if (valueTransmission == 0.0){ return -1; } double preuIntermedi = price - (valueTransmission + PAC1Ex2.calculateValuationByMileage(price, mileage)); double preuDevaluacio = PAC1Ex2.calculateValuationByAge(preuIntermedi,age); System.out.println("Your vehicle is now valued at " + preuDevaluacio +"€"); return preuDevaluacio; }
However, when I run the code I can see the message but I’m not returning -1. I have tried to match the return as 0.0 and then change it to -1 but this does not work (see code following the //HERE comment). Which one would be the best way to do it?
Thanks in advance
Advertisement
Answer
To return specific states, you basically have FOUR options:
You can use constants:
public static final [type] [varname] = [value];
. This is used for specific messages/states, and can also be used with classes.You can use Optional:
Optional<Integer>
. This only works with classes. ReturnOptional.empty();
to indicate bad state.To indicate invalid return values, you can also simply use a wrapper class. As you’re using
double
, the wrapper class would beDouble
. Soreturn null;
, and whenever you retrieve the valueDouble valueTransmission = PAC1Ex2.calculateValuationByTransmission(price, transmission); if (valueTransmission == null){ return -1; // or even better, also return null here if applicable }
As @Socowi pointed out, you can also use Exceptions to signal critically bad input values. So I rewrote your code to use Exception Handling:
Code:
public class PAC1Ex2 { // define our own exception here static public class InvalidTransmissionException extends IllegalArgumentException { private static final long serialVersionUID = 1421105202322188571L; public InvalidTransmissionException(final String pMessage) { super(pMessage); } } public static double calculateValuationByTransmission(final double price, final char transmission) { if (transmission == 'A') { return price * 0.05; } else if (transmission == 'M') { return price * -0.05; } else { throw new InvalidTransmissionException("Transmission [" + transmission + "] invalid! Transmission must be: [A] or [M]!"); // System.out.println("Transmission must be: 'A' or 'M'"); // return 0; } } public static double calculateValuation(final double price, final int mileage, final int age, final char transmission) { if (price < 0.0 || mileage < 0 || age < 0) { System.out.println("Price, mileage and age must be a positive number"); // we also could use exceptions here return -1; } //HERE try { final double valueTransmission = PAC1Ex2.calculateValuationByTransmission(price, transmission); final double preuIntermedi = price - (valueTransmission + PAC1Ex2.calculateValuationByMileage(price, mileage)); final double preuDevaluacio = PAC1Ex2.calculateValuationByAge(preuIntermedi, age); System.out.println("Your vehicle is now valued at " + preuDevaluacio + "€"); return preuDevaluacio; } catch (final InvalidTransmissionException e) { return -1; // or even pass that exception up forther by a) not catching it, or b) writing "throw e;" } } private static double calculateValuationByAge(final double pPreuIntermedi, final int pAge) { // TODO Auto-generated method stub // dummy method return 0; } private static double calculateValuationByMileage(final double pPrice, final int pMileage) { // TODO Auto-generated method stub // dummy method return 0; } }
Warning: comparing values of floats and doubles is always done via some tolerance tests, so this might bear strange results. Also be careful with testing agains Double.NaN, because you cannot compare a value like if (x == Double.NaN) ...
but must instead use Double.isNaN(x)
.
Usually you should use Wrappers first, if one exception state suffices. If you need more, use constants.