0

用户通过配置支持 userType 和 userFunction:

{"userType": "com.user.Person", "userFunction": "com.user.userFunction"}

我们希望获取用户数据并将数据提供给 userFunction:

public class DataConsumer<T> {
    //get data from some place, such as kafka
    T data;
}
process() {
    String userType = userInput();
    DataConsumer<userType> dataConsumer = new DataConsumer<userType>(); // error because generic class's type name don't support String or Class 
    userFunction(dataConsumer.data); // We get this function by reflection
}

// This is ok in the user side
userFunction(userType data) {
    data;
}

我怎样才能在没有错误的情况下实现这个功能?如果不可能,还有其他方法吗?

最后,我使用 Object 来代表所有类型名称。但用户必须手动将 Object 类型转换为 userType。有没有更好的办法?

{
    String userType = userInput();
    DataConsumer<Object> dataConsumer = new DataConsumer<Object>(); // ok
    userFunction(dataConsumer.data); 
}

userFunction(Object data) {
    (userType)data;
}
4

2 回答 2

0

可以使用 Reflection API 来获取 Classes、Methods 和 Fields 的实例;

首先,您可以使用

 Class c = Class.forName("Class Name");

您可以使用从该类中获取方法

 c.getDeclaredMethod("Method Name");

字段也是如此

 c.getDeclaredField("Field Name");
于 2018-10-17T07:51:10.833 回答
0

啊,你应该知道java中的泛型在大多数情况下只是编译器中的语法糖,所以如果你不知道运行时类型,只需使用通配符或原始类型:
MyClass<?> myClass = new MyClass<>();MyClass myClass = new MyClass();
但是如果用户输入总是像那个 String 这样的已知类型那么你可以这样做:
MyClass<String> myClass = new MyClass<>();
你也可以像这样在你的类中创建泛型构造函数:

public class MyClass<T> {
    T data;
    public <T> MyClass(T data) {this.data = data;}
}

所以泛型类型将是您传递给它的数据类型 - 但这仅在编译时存在,在运行时 java 在这里忽略所有泛型,就像这是有效的 java 代码:

List<String> strings = new ArrayList<>();
strings.add(“a”);
List<Integer> integersKindOf = (List)strings;
integersKindOf.remove(“a”);

Java 仅保存泛型类型的字段、超类(class MyMap extends HashMap<String, Integer>-您可以使用泛型参数获取该超类型)和方法。但它们不在运行时使用,但反射可用于读取该类型。
对于局部变量,这是不可能的,并且由于类型擦除而无用。

不安全的泛型转换也有常见的模式,但在使用它时应该非常小心:

public <T> T doSomething(String type) {
    return (T) Class.forName(type).newInstance();
}

然后 this 可以这样使用:
ArrayList<Whatever> list = doSomething("java.util.ArrayList");
但也可以这样使用:
Integer list = doSomething("java.util.ArrayList");
而且 this 会在运行时抛出异常,这就是它非常不安全的原因。

于 2018-10-17T10:01:56.533 回答