假设我有这个通用类A
:
public class A<E> {
public A(E e) {}
}
如何知道此类的两个实例是否具有相同的类型参数<E>
?
我试过了:
public static void main(String[] args) {
A<String> aString = new A<>("a");
A<Integer> anInt = new A<>(0);
System.out.println(aString.getClass().isInstance(anInt));
}
哪个输出true
。我想这是有道理的,因为他们有同一个班级。但是,如果您尝试这样做:
A<String> anotherString = new A<Integer>(-1);
它不会编译,因为类型参数不同。如何在运行时知道两个类型参数是否不同/等效?换句话说,我需要一个可以比较两个变量并根据类型参数返回false
的方法。
编辑:好的,似乎可能无法实现。我将首先尝试解释为什么我想要做到这一点,也许还有另一种实现方法。如果您希望我发布不同的问题,请告诉我。
我有这个方法:
public void someMethod(A<String> aString) {
System.out.println("I got called!");
}
如何通过反射确保给出的参数实际上是A<String>
?
如果我试试这个:
A<Integer> anInt = new A<>(0);
Method method = Main.class.getMethod("someMethod", anInt.getClass());
method.invoke(new Main(), anInt);
它仍会打印出“我被叫了!”信息。我怎样才能确保不会发生这种情况? (如果可能的话)。
答案 0 :(得分:1)
类型信息仅在编译时使用。因此在运行时类型信息将丢失。如果要在运行时进行某些比较,可以将类类型存储在变量中。
答案 1 :(得分:0)
使用泛型的全部原因是确保如果代码编译,那么它不会导致任何运行时问题。您正在搜索没有问题的问题。您的代码在编译时失败的原因是您明确提供了不兼容的引用类型,只要这些类型具有共同的超类型<E>
答案 2 :(得分:0)
您可以捕获类型的一种方法是使实例成为A
的匿名子类:
A<String> aString = new A<String>("a") {};
A<Integer> anInt = new A<Integer>(0) {};
然后你可以看看例如aString.getClass().getGenericSuperclass()
在运行时获取泛型类型。
如@James_D所述,您可以通过使A
抽象来强制执行此操作。
答案 3 :(得分:0)
如其他答案中所述,通用类型信息不会在运行时保留。如果您需要这些信息,那么在我的类中定义一个属性来表示它是有意义的:
public class A<E> {
private final Class<E> type ;
private E value ;
public A(E e, Class<E> type) {
this.type = type ;
this.value = value ;
}
public Class<E> getType() { return type ; }
// other methods, etc...
}
然后你可以做
A<Integer> aInt = new A<>(1, Integer.class);
A<String> aString = new A<>("", String.class);
你可以检查
aInt.getType() == aString.getType()