5

我正在创建一个MethodPointer类以模拟 C++ 中函数指针的功能。起初,我只是用Objects 来做所有事情,但后来我有了一个想法——为什么不让它真正通用呢?

问题出现在这个构造函数中,它试图用签名调用另一个构造函数MethodPointer(Class<T> clazz, String methodName, Class<?> ... paramClasses)

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

我认为这可以正常工作,但我收到以下编译器错误:

The constructor MethodPointer<T>(Class<capture#1-of ? extends Object>,
String, Class<?>[]) is undefined

所以,很困惑,我这样做了:

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>

我想问题是我不明白什么Class<capture#1-of ? extends Object>意思。我认为,由于从参数T推断出的类型,调用返回一个类型的对象是必要的。不过,显然情况并非如此。有人可以解决我的困惑吗?T objectobject.getClass()ClassClass<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;
    }
4

3 回答 3

7

SLaks 的回答指出object.getClass()衰减到Class<? extends Object>, 来解释编译错误。但是投射Class<T>.

getClass“返回运行时类”它被调用的对象。例如,如果我们在 aMethodPointer<Number>中,那么object is-a Number但它的运行时类型可能是Integer,Double等。这告诉我们强制object.getClass()转换Class<T>为不安全,因为Class<Integer>andClass<Number>是不同的对象,代表不同的类——这种区别似乎非常相关你正在尝试做的事情的正确性。

那么解决方案是什么?好吧,不要投。坚持Class<T>从来电者那里拿走。

于 2013-08-13T00:55:04.380 回答
5

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

Javadocs说:

实际结果类型是Class<? extends |X|>调用|X|getClass 的表达式的静态类型的擦除。

例如,new ArrayList<String>().getClass()返回 a Class<? extends ArrayList>,而不是Class<? extends ArrayList<String>>

这也意味着getClass()对类型参数的调用衰减为Class<? extends Object>.

于 2013-08-12T23:38:58.120 回答
0

如果您不需要指定的类类型,则可以使用

Class<?>

为你的参数。

所以你的类有一个未绑定的类型。

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

obj.getClass().getDeclaredConstructor(Class<?> parameterTypes)
于 2013-08-13T07:28:25.760 回答