Java,双返回函数,失败后返回什么?

I am moving from PHP to Java and I'm a little struggled.

I have this method like this that I use to get some data from MySQL database and I would like to treat the failure if no data got from database.

public double getRate() {
    double ret;
    try {
        // do a select query
        PreparedStatement stmt = conn.prepareStatement("SELECT `rate` FROM `rates` LIMIT 1");
        ResultSet rs = stmt.executeQuery();

        // get result
        rs.absolute(1);
        ret = rs.getDouble(1);

        // close the resources
        rs.close();
        stmt.close();
    }

    // this catches only the SQL errors (if I am right)
    catch (SQLException ex) {
        ex.printStackTrace();
    }

    // THIS IS WRONG BECAUSE "variable ret might not have been initialized"
    return ret;
}

In PHP we can return whatever in case of failure like this:

<?php

public function getRate() {
    $ret = db::getOne("SELECT `rate` FROM `rates` LIMIT 1");
    if ($ret) { 
        return $ret; // row has been found, so we return it
    } else {
        return false; // row hasn't been found, so we return false --> THIS is what I need to do in Java
    }
}

?>

So how to treat a failure in Java methods/functions where I have nothing to return?

Initialize your double variable with a control value. If it is not changed when exiting the method, then something went wrong.

The control value can be something you do not expect to get from the query, so for rates it could be a negative number, say -1 since rates can't be negative.

double ret=-1.00d;

You could make your method return an object of the double wrapper class Double. Then you could return a null pointer in case of some failure.

public Double getRate() {
    ...
    if(ok)
        return new Double(ret);
    else
        return null;
}

You have several options:

  • throw an exception, and catch this by the code which calls the method. This works well, is a nice way to handle it. But requires a lot of additional try-catch statements
  • Return -1 on error. This is also a very common way to do if you work with natural numbers only
  • always return a result object, which contains a the output and a success/error status
  • Use the Double Class instead, and return null on fail

I am adding a sample code so you can understand how to handle such scenarios. If your default value does not changes,it means there was nothing that matched your query.

public double methodName(int arg)
{
    double risk=0.0;
    String query = null;
    PreparedStatement stm = null;
    ResultSet r = null;

    Connection con=null;

    try{
        con=ConnectionDB.getConnection();
        if(con!=null)
        {
            query="select risk from table where year="+arg;
            stm = con.prepareStatement(query);
            r = stm.executeQuery();
            if(r.next())
            {
                risk=r.getDouble(1);
            }

        }

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    finally{
        try {
            if (r != null) {
                r.close();
            }
            if (stm != null) {
                stm.close();
            }
            if(con!=null)
            {
                con.close();
            }

        } catch (Exception e) {
            System.out.println("" + e);
        }
    }
    return risk;


}

In Java, you can't return double from one place and boolean from another. What you could do is, initialize your Double (wrapper of double primitive) value like:

Double ret = null;

And if there are no rows or any SQLException, you would return this value back to caller. In called method you could do something like:

Double rate = getRate();
if (rate == null) {
    //no row found
} else {
    //i have the row. continue with business logic
}

You could return an OptionalDouble, which makes it obvious to the caller that they need to handle the case of the result not being found:

try {
    // get ret
    return OptionalDouble.of(ret);
} catch (SQLException ex) {
    return OptionalDouble.empty();
}

In your Java example, when you talk about a "failure", you are talking about an unexpected error (e.g. a SQL Exception, a non-expected error in the DB access).

Nevertheless, in your PHP example, when you talk about a "failure", you are talking about a normal scenario (No data in database).

So, both examples are quite different.

In my opinion, if I get an unexpected sitution, I wouldn't return any value, I'd throw an exception. I usually return null, -1 and this kind of values in normal and expected scenarios where there isn't data to return.