接受一个类对象或另一个类对象的方法

Phi*_*ohn 8 java

我有两种方法,如下所示

private List<Long> getIds(String name, List<Cat> cats) {
    List<Long> catIds = new ArrayList<>();
    for (Cat cat : cats) {
        if (cat.getName().equals(name)) catIds.add(cat.getId());
    }
    return catIds;
}

private List<Long> getIds(String name, List<Dog> dogs) {
    List<Long> dogIds = new ArrayList<>();
    for (Dog dog : dogs) {
        if (dog.getName().equals(name)) dogIds.add(dog.getId());
    }
    return dogIds;
}
Run Code Online (Sandbox Code Playgroud)

我的猫狗课程如下

public class Cat {
    String name;
    Long id;
    // additional variables
    // getters and setters
}

public class Dog {
    String name;
    Long id;
    // additional variables
    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)

为了避免冗余,我想将上述两种方法转换为单一的泛型方法.

我尝试了以下内容

private List<Long> getIds(String name, List<T> objects) {
    List<Long> ids = new ArrayList<>();
    for (T object : objects) {
        if (object.getName().equals(name)) ids.add(object.getId());
    }
    return ids;
}
Run Code Online (Sandbox Code Playgroud)

但它没有成功,因为它抱怨通用T没有getNamegetId

这里CatDog在建的Java类.因此,我不能执行继承并Animal为它们提供超类nameid作为数据变量.

有没有办法在不实现继承的情况下完成合并上述两种方法?

Coo*_*tri 1

好吧,我知道你不能使用任何类型的继承。下面是一个使用 Reflection API 的简短解决方案:

private static List<Long> getIds(String name, List<?> objects) {
    List<Long> ids = new ArrayList<>();
    for (Object object : objects) {
        try {
            Method getName = null;
            Method getId = null;

            for (Method method : object.getClass().getMethods()) {
                if (method.getName().equals("getName") && method.getReturnType().equals(String.class) && method.getParameterTypes().length == 0) {
                    getName = method;
                }
                if (method.getName().equals("getId") && method.getReturnType().equals(Long.class) && method.getParameterTypes().length == 0) {
                    getId = method;
                }
                if (getName != null && getId != null && getName.invoke(object).equals(name)) {
                   ids.add((Long) getId.invoke(object));
                   break;
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    return ids;
}
Run Code Online (Sandbox Code Playgroud)

  • 一些建议:使用“equals”来比较字符串,并在类没有该属性的情况下引发“IllegalArgumentException”。另外,`List&lt;Object&gt;` 太严格了;使用“列表&lt;?&gt;”。 (2认同)
  • @PhilipJohn说实话,我个人会接受这个答案,但如果找不到该方法,我也会抛出一个“IllegalArgumentException”,而不是默默地忽略没有这些方法的元素。恐怕这与 [Java 中的 Duck Typing](https://en.wikipedia.org/wiki/Duck_typing#In_Java) 非常接近 (2认同)