Java 如何确定泛型中的参数类型是否正确
我正在编写一个带有以下必需方法签名的映射实现 我需要确保值的类型正确。我认为如果两种类型不相等,该检查将导致异常,但事实并非如此。还有什么可以检查的吗Java 如何确定泛型中的参数类型是否正确,java,generics,casting,map,error-handling,Java,Generics,Casting,Map,Error Handling,我正在编写一个带有以下必需方法签名的映射实现 我需要确保值的类型正确。我认为如果两种类型不相等,该检查将导致异常,但事实并非如此。还有什么可以检查的吗 public boolean containsValue(Object value) { try { V temp = (V) value; } catch (Exception e) { throw new ClassCastException("Value is not of correct
public boolean containsValue(Object value) {
try {
V temp = (V) value;
} catch (Exception e) {
throw new ClassCastException("Value is not of correct type");
}
...
它不抛出异常的原因是映射不能包含其他类型的对象,因此正确答案为false
至于您的问题,由于类型擦除,无法查看传递的对象是否与泛型类型相同。由于类型擦除,您无法使用标准的
instanceof
运算符。规范方法是将类本身或其实例传递到某个地方
然后可以使用反射检查实例类型:
private Class<V> clazz; // somehow this gets set
public boolean containsValue(Object value){
if(clazz.isInstance(value)){
// safe:
V temp = (V) value;
}
注意:这保证了这是类型安全强制转换,但不要求类型相同,例如,V
可以是Number
,但value
可以是Integer
类型
只要获得clazz
,您就可以在构造函数中强制执行它:
public class MyMap<K,V>{
private final Class<V> clazz;
public MyMap(Class<V> clazz){
this.clazz = clazz;
}
...
公共类MyMap{
私人期末班;
公共MyMap(类clazz){
this.clazz=clazz;
}
...
类的初始值设定项可能类似于:
MyMap<Integer,String> foo = new MyMap<Integer,String>(String.class);
MyMap foo=newmymap(String.class);
对于这类事情,我通常赞成在构造函数中传递类型,并将字段标记为
final
,因为语义和限制会阻止您更改该字段,这是合理的,因为实例通常依赖于编译时保证,假定类型参数不变 为什么需要V类型的值?映射接口是这样定义的,不是偶然的
您应该接受作为对象的值,然后调用value.equals(地图中的其他值)
例如:
public boolean containsValue(Object value) {
V v1 = ...;
V v2 = ...;
V v3 = ...;
return value.equals(v1) || value.equals(v2) || value.equals(v3);
}
假设地图中有三个值v1、v2、v3。
v1、v2、v3的类型和参数值无关紧要,因为equals方法是在Object中定义的,您可以随时调用它来比较对象。如果值的类型确实不同,无法与V实例进行比较,那么它的equals方法将抛出ClassCastException,除非您捕获它,否则它将被传播r.别担心。好吧,我有点明白你的意思,但是我该如何以及在哪里放置clazz呢?@Jeff:它只需要是类中的一个字段。我建议在构造函数中设置它的值。所以,它看起来像这样:public class MyMap{public MyMap(class clazz){this.clazz=clazz;}是它自己的独立构造函数吗?它如何与我已经编写的构造函数集成?@Jeff:你需要修改你当前的构造函数。编译器会对该泛型强制转换发出警告。不要忽略这些警告。如果要求它为V型,你就违反了
containsValue()的约定
方法,当value.equals(v)
的映射中存在值v
时,该方法返回true(或者如果它们都为null),无论value
+1的类别如何,人们总是试图强制对象成为值的类型,这与Map中方法的规范相矛盾value
是传入的外部对象,而不是Map中的对象
public boolean containsValue(Object value) {
V v1 = ...;
V v2 = ...;
V v3 = ...;
return value.equals(v1) || value.equals(v2) || value.equals(v3);
}