Java 为什么要将类的泛型转换为类<;T>;不安全的? 我制作了一个 MethodPointer 类,以模拟C++中函数指针的功能。起初,我只是用对象做所有事情,但后来我有了一个想法——为什么不让它真正通用

Java 为什么要将类的泛型转换为类<;T>;不安全的? 我制作了一个 MethodPointer 类,以模拟C++中函数指针的功能。起初,我只是用对象做所有事情,但后来我有了一个想法——为什么不让它真正通用,java,generics,casting,type-inference,Java,Generics,Casting,Type Inference,问题出现在这个构造函数中,它试图调用另一个带有签名MethodPointer(Class clazz,String methodName,Class…paramClasses)的构造函数: 问题是getClass()忽略类型参数 他们说: 实际的结果类型是ClassSLaks的回答指出object.getClass()衰减为Class如果不需要指定的类类型,可以使用 Class<?> 类 为您提供参数 因此,您的类有一个未绑定的类型 如果你想得到一个实例,你可以这样使用它: ob

问题出现在这个构造函数中,它试图调用另一个带有签名
MethodPointer(Class clazz,String methodName,Class…paramClasses)的构造函数


问题是
getClass()
忽略类型参数

他们说:


实际的结果类型是
ClassSLaks的回答指出
object.getClass()
衰减为
Class如果不需要指定的类类型,可以使用

Class<?>
为您提供参数

因此,您的类有一个未绑定的类型

如果你想得到一个实例,你可以这样使用它:

obj.getClass().getDeclaredConstructor(Class<?> parameterTypes)
obj.getClass().getDeclaredConstructor(类参数类型)

由于在
MethodPointer
构造函数的第一个参数中指定了类型参数
t
,向下转换不是安全的吗?@KevinBowersox:是的,它是安全的,但是
getClass()
的编译时类型专门忽略类型参数。不安全并不总是意味着不安全。它真正的意思是编译器(受JLS约束)无法确认类型安全性。@JeffGohlke下面的内容可能会对
capture#1-of
的意思有所帮助:@yshavit I’m with you-我提到你只是为了引起你的注意,因为你的(投票)评论似乎支持它是一个安全类型。顺便说一句,如果您愿意使用,请查看他们的类。+1如果
T
是非最终类型,OP可能会根据调用的构造函数得到不一致的结果。使用
Class@SLaks这肯定会有帮助,相反,投下这样的球是安全的。实际上我忘记了
getClass
不会返回
Class@SLaks:甚至
类谢谢你解释这个警告。这对于解释为什么它不安全(这是最初的问题)是有意义的。
public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
    this((Class<T>) object.getClass(), methodName, paramClasses);
    this.object = object;
}
Unchecked cast from Class<capture#1-of ? extends Object> to Class<T>
public class MethodPointer<T> {

    //Logger instance
    private static final Logger LOGGER = Logger.getLogger(MethodPointer.class);

    //Object fields
    private final Method method;
    private ArrayList<Object> args = new ArrayList<Object>();
    private T object = null;


    //Constructors
    public MethodPointer(Method method) {
        this.method = method;
    }

    public MethodPointer(Class<T> clazz, String methodName, Class<?> ... paramClasses) {
        Method theMethod = null;
        try {
            theMethod = clazz.getMethod(methodName, paramClasses);
        }
        catch(NoSuchMethodException nsme) {
            LogUtil.log(LOGGER, Level.ERROR, "Unable to find method " + methodName + " in " + clazz.getSimpleName(), nsme);
        }
        method = theMethod;
    }

    public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
        this((Class<T>) object.getClass(), methodName, paramClasses);
        this.object = object;
    }
Class<?>
obj.getClass().getDeclaredConstructor(Class<?> parameterTypes)