Java接受不同类型的参数而不会重载

Var*_*Agw 2 java java-8

这是一个非常简单的例子:

private boolean f(List x) {
    return x != null && !x.isEmpty();
}

private boolean f(Map x) {
    return x != null && !x.isEmpty();
}
Run Code Online (Sandbox Code Playgroud)

两个函数内部的代码相同,它们只对不同的对象进行操作.我想将它们合并到一个函数中以避免代码重复.

我尝试过类似的东西:

private <T> boolean f(T x) {
    return x != null && !x.isEmpty();
}
Run Code Online (Sandbox Code Playgroud)

但它给出了错误 x.isEmpty()

T.J*_*der 13

如果要使用的部分由两个类实现的接口覆盖,请使用该接口.

但在您的情况下,List并且Map不共享提供的界面isEmpty,因此您的选择是:

  1. 重载(以下是您的代码不变)

    private boolean f(List x) {
        return x != null && !x.isEmpty();
    }
    private boolean f(Map x) {
        return x != null && !x.isEmpty();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 接受Object和使用instanceof分支机构

    private boolean f(Object x) {
        // (roughly)
        if (x == null) {
            return false;
        }
        if (x instanceof List) {
            return !((List)x).isEmpty();
        }
        if (x instanceof Map) {
            return !((Map)x).isEmpty();
        }
        throw new IllegalArgumentException(); // Or whatever
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 接受Object并使用反射来获取isEmpty方法(如果有的话)并调用它

    private boolean f(Object x) {
        // (roughly)
        try {
            return x != null && !(boolean)x.getClass().getMethod("isEmpty").invoke(x);
        } catch (Exception e) {
            throw new IllegalArgumentException(); // Or whatever
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

其中,重载对我来说似乎是最干净的方法,尤其是因为如果你尝试使用它无法处理的类型(而其他类型是运行时错误,blech),它会给你一个编译f时错误,但它是(在至少是一个意见问题.