Tworzę klasę MethodPointer
w celu symulacji funkcjonalności wskaźników funkcyjnych z C++. Na początku robiłem wszystko z zaledwie Object
s, ale potem pomyślałem - dlaczego nie uczynić tego naprawdę generycznym?Dlaczego rzucanie klasy generycznej na klasę <T> jest niebezpieczne?
Problem był w tym konstruktora, który próbował wywołać inny konstruktor z podpisem MethodPointer(Class<T> clazz, String methodName, Class<?> ... paramClasses)
:
public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
this(object.getClass(), methodName, paramClasses);
this.object = object;
}
I zakładanego to będzie działać dobrze, ale otrzymałem następujący błąd kompilatora:
The constructor MethodPointer<T>(Class<capture#1-of ? extends Object>,
String, Class<?>[]) is undefined
więc mylić, zrobiłem to:
public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
this((Class<T>) object.getClass(), methodName, paramClasses);
this.object = object;
}
To teraz kompiluje, ale otrzymuję następujące ostrzeżenie:
Unchecked cast from Class<capture#1-of ? extends Object> to Class<T>
Myślę, że problemem jest to, że ja nie rozumiem, co Class<capture#1-of ? extends Object>
środków. Myślałem, że ponieważ typ T
jest wywnioskowany z parametru T object
, że będzie konieczne, który wywołując object.getClass()
zwraca obiekt Class
typu Class
. Najwyraźniej tak nie jest. Czy ktoś może wyjaśnić moje zamieszanie?
Pełna deklaracja klasy i wszyscy konstruktorzy:
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;
}
Btw, jeśli jesteś otwarty do korzystania [Guava] (https://code.google.com/p/ guava-libraries /), sprawdź ich klasę ['Invokable'] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/reflect/Invokable.html). –