泛型方法是否可以从您传递给它的类型中调用方法

Is it possible for a generic method to call a method from the type you pass into it

我有一个方法需要在很多class中使用。此方法旨在创建给定对象类型的新对象列表。此方法需要从每个 class(同一类方法的不同实现)中调用另一个方法。

我不想将方法 copy/paste 放入每个 class 并每次都更改对象类型,而是想创建一个带有泛型方法的泛型 class 来调用必要的方法来自每个 class。这可能吗?

这是我正在尝试做的事情:

public class Conversion<E> {
    public static <E> List<E> toList(String str) {
        //The string needs to be split because it contains
        //the information to create multiple objects
        String[] listArray = str.split(".");
        List<E> list = new ArrayList<E>();
        for (String s : listArray) {
            //E.fromString() creates an object of the type E
            //It is a static method
            list.add(E.fromString(s));
        }
    return list;
    }
}

当我尝试这个时,Eclipse 给我一个错误,说 fromString(String) 对于类型 E 是未定义的。我想要的有可能吗?

您可以创建一个接口,该接口执行从 String 到类型 E 的对话,并在您的方法中传递对象类型。如下所示:

public static <E> List<E> toList(String str, YourType<E> yourObject) {
    //The string needs to be split because it contains
    //the information to create multiple objects
    String[] listArray = str.split(".");
    List<E> list = new ArrayList<E>();
    for (String s : listArray) {
        //E.fromString() creates an object of the type E
        //It is a static method
        list.add(yourObject.fromString(s));
    }
return list;
}
}

interface YourType<E>{
     E fromString(String s);
}

最简单的修改是使用strategy pattern。 定义一个接口如

interface Parser<T> {
    T fromString(String s);
}

并将签名更改为

public static <E> List<E> toList(String str, Parser<E> parser) {

然后使用parser.fromString(s),而不是E.fromString

示例用法

interface User {}

class UserParser implements Parser<User> {
    @Override
    public User fromString(String s) {
        return new User() {};
    }
}



toList("a.b.c", new UserParser());

假设:

如果有一些语言特性可以使静态方法成为接口契约的一部分,也许你可以像这样摆脱困境

interface Parsable<T> {
    static T fromString(String s); // will not compile
}

public static <E extends Parseable<E>> List<E> toList(String str)

但这在 Java 中永远不会发生。不过,如果有另一种允许它的强类型语言,也不会感到惊讶。

关于它是否应该包含在 TypeScript 中似乎有些 hot discussion

可以这样做,但这非常不安全

public static class Conversion {
        public static <E> List<E> toList(String str, Class<E> clazz)
                throws Exception {
            //The string needs to be split because it contains
            //the information to create multiple objects
            String[] listArray = str.split("\.");
            List<E> list = new ArrayList<E>();
            Method fromStringMethod = clazz.getMethod("fromString", String.class);
            for (String s : listArray) {
                //E.fromString() creates an object of the type E
                //It is a static method
                Object object = fromStringMethod.invoke(null, s);
                list.add((E) object);
            }
            return list;
        }
    }


    public static class FromString {
        private String field;

        public FromString() {
        }
        public FromString(String st) {
            this.field = st;
        }
        static public FromString fromString(String st) {
            return new FromString(st);
        }
        @Override
        public String toString() {
            return "FromString{" +
                    "field=" + field +
                    '}';
        }
    }

    @Test
    public void test() throws Exception {
        System.out.println(Conversion.toList("one.two.three", FromString.class));
    }

输出:

[FromString{field=one}, FromString{field=two}, FromString{field=three}]