简体   繁体   中英

Java Static Method, Wildcard / Generic Return Type

I'm building an API, which uses abstract classes, to invoke static methods. Some Java Pseudocode:

public abstract class APIBaseClass {

    public static List<?> myMethod(Class<?> clazz, MyConverter converter, List<Object> objects) {
        return objects.stream()
                  .map(object -> converter.convertObjectToType(object, clazz))
                  .collect(Collectors.toList());
    }

}

And, where myMethod is invoked:

public abstract class MyAPIClass extends APIBaseClass {

    public static List<MyClassType> invokingMethod(MyConverter converter, List<Object> objects) {
        List<MyClassType> list = myMethod(MyClassType.class, converter, objects);
        ...
        return list;
    }
}

myMethod compiles, as expected. And, invokingMethod does not compile, also as expected, due to incompatible types:

Required: List<blah.blah.blah.MyClassType>
Found:    List<capture<?>>

It compiles without errors or warnings if I: (1) @SuppressWarnings("unchecked") on invokingMethod , and (2) cast the result of myMethod to a list of MyClassType , when invoked, ie List<MyClassType> list = (List<MyClassType>) myMethod(MyClassType.class, converter, objects); . However, there's no transparency that this would be necessary to anybody using the API, which feels less than ideal.

What are my options for myMethod returning the a list of the type it is invoked with to invokingMethod , while maintaining my abstract classes and static methods, while ideally improving usability within invokingMethod ?

Any suggestions or alternative ideas are welcome.

Thanks in advance.

The fact that your classes are abstract is completely irrelevant. If you make them abstract to prevent their instantiation, and use inheritance to avoid having to specify the class name, then that's an antipattern, which doesn't use abstract classes for polymorphism as they're intended to be used. Just add a private constructor to the classes, and use static imports.

Now, regarding the question itself, you need to make the method generic, and the MyConverter.convertObjectToType() method generic, too:

public static <T> List<T> myMethod(Class<T> clazz, MyConverter converter, List<Object> objects) {
    return objects.stream()
              .map(object -> converter.convertObjectToType(object, clazz))
              .collect(Collectors.toList());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM