Simplify code and avoid instanceOf and null check

时间:2019-04-08 13:46:53

标签: java object null optional instanceof

I want to simplify the code (e.g. by using Optionals)

private String formatValue(Object value) {
    if (value == null) {
        return null;
    } else if (value instanceof Date) {
        return MyUtils.formatDate((Date)value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
    }

    return value.toString();
}

value can be: null, String, Date

4 个答案:

答案 0 :(得分:6)

I'd handle it with overloading:

private String formatValue(String value) {
    return value;
}
private String formatValue(Date value) {
    return MyUtils.formatDate(value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}

...and fix any code passing it null.

If you really have to handle null, then:

private String formatValue(String value) {
    return value;
}
private String formatValue(Date value) {
    return value == null ? null : MyUtils.formatDate(value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}

The above works provided the type of what you're passing in is known at compile-time, which normally would be the case. But if you have to handle the possibility that the only type known at compile-time is Object, you can add an Object version as well:

private string formatValue(Object value) {
    if (value instanceof Date) {
        return this.formatValue((Date)value);
    }
    return value == null ? null : value.toString();
}

That starts feeling like more code, but it lets the normal path (where the type is known) go straight to the appropriate method, and you'd only supply this if you were dealing with something dynamic where you were stuck with Object.

Or you can just have the Object version. It doesn't have fewer checks, but it seems a bit simpler and clearer to me.

答案 1 :(得分:2)

If you really want a functional version of your code, you can do this (using 2 Optionals):

private String formatValue(Object value) {

    return Optional.ofNullable(value)
            .map(v -> Optional.of(v)
                        .filter(d -> d instanceof Date)
                        .map(d -> MyUtils.formatDate((Date) d, 
                                      Constant.DATE_FORMAT_YYYYMMDD_HHMMSS))
                        .orElseGet(() -> v.toString()))
            .orElse(null);
}

This is hard to read, though; so I'd personally keep your original version.

答案 2 :(得分:1)

You can use Optional from java 8:

return Optional.ofNullable(value).filter(v -> v instanceof Date || v instanceof String)
    .map(v -> v instanceof Date ? MyUtils.formatDate((Date)v, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS : v)
    .orElse(null);

答案 3 :(得分:0)

For Date as one of Date or String, one cannot avoid instanceOf. As null is not a Date:

if (value instanceof Date) {
    value = MyUtils.formatDate((Date)value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}
return Optional.ofNullable(value).map(String.class::cast);

A Object::toString would be safer, but now a fail-fast cast exception would be thrown on erroneous values.