我有一个Java接口,它需要Object类型的变量输入参数。
public interface TestInterface <I,O>{
public O invoke(I...inputs);
}
public class FirstClass implements TestInterface<String, Object>{
@Override
public Object invoke( String... input ){
System.out.println("inside VO");
return "Tet";
}
}
我试图调用它的主类。
public class Main{
public static void main( String[] args ){
FirstClass voDS=new FirstClass();
TestInterface ds=voDS;
ds.invoke( "abc" );
}
}
当我调用它时,我得到ClassCast Exception Object not compatible with String error
。是否有任何解决方法可以调用此方法?
答案 0 :(得分:1)
在我给你一个答案之前,你首先要在这个正字法上与我达成一致:
此片段:
FirstClass voDS = new FirstClass();
TestInterface ds = voDS;
ds.invoke("abc");
......相当于:
TestInterface voDS = new FirstClass();
voDS.invoke("abc");
这是创建集合时使用的模式;使用接口而不是具体类。
有了这个,让我们观察一下关于界面的好奇属性:
public O invoke(I...inputs);
嘿,这是一个类型参数,不是吗?类型I
与声明TestInterface<I, O>
相关联。这意味着当我们使用接口抽象时,我们期望一些泛型类型I
。
现在,我们来具体实现......它不共享相同的通用边界!
public class FirstClass implements TestInterface<String, Object>
糟糕,由于类型擦除,如果我们尝试将其用作具体实现,我们将获得原始类型,并且我们可能使用vararg数组获得ClassCastException
。 / p>
修复很简单:在声明与您的支持类相关的接口实例时使用您的具体类型。
TestInterface<String, Object> voDS = new FirstClass();
voDS.invoke("abc");
现在,您的界面知道它应该在varargs字段中应该使用哪种类型的参数,以及它应该返回的内容。
现在这不是理想对泛型的使用 - 在许多情况下,您必须向后备类提供泛型类型才能使其正常工作。