2016-08-18 94 views
3

您好我在使用java中的泛型类型时遇到了问题。实际的问题是,当我在方法声明上使用泛型时工作正常。然后,如果我添加一个泛型类型的接口声明代码不会编译。以下是工作代码:为什么JAVA无法在接口中使用泛型时编译

public interface IRuntimeConvert { 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz); 
} 

public class RuntimeConvertImpl implements IRuntimeConvert { 

    private final Map<String, Object> hashMap; 

    public RuntimeConvertImpl(Map<String, Object> hashMap) { 
     this.hashMap = hashMap; 
    } 

    @Override 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz) { 
     try { 
      return clazz.cast(hashMap.get(o)); 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 
} 

public static void main(String[] args) { 

    Map<String, Object> hashMap = new HashMap<>(); 
    hashMap.put("s", "string"); 
    hashMap.put("i", 0); 
    hashMap.put("l", 0L); 

    IRuntimeConvert rtConvert = new RuntimeConvertImpl(hashMap); 

    String s = rtConvert.convertInstanceOfObject("s", String.class); 
    System.out.println(s); 
    Integer i = rtConvert.convertInstanceOfObject("i", Integer.class); 
    System.out.println(i); 
    Long l = rtConvert.convertInstanceOfObject("l", Long.class); 
    System.out.println(l); 
} 

上面的代码正在编译。当我做出以下更改时,代码不可编译。

public interface IRuntimeConvert<S> { 

    public <T> T convertInstanceOfObject(String o, Class<T> clazz); 

    public S getSomething(S s); 
} 

public class RuntimeConvertImpl implements IRuntimeConvert<Object> { 

    private final Map<String, Object> hashMap; 

    public RuntimeConvertImpl(Map<String, Object> hashMap) { 
     this.hashMap = hashMap; 
    } 

    @Override 
    public <T> T convertInstanceOfObject(String o, Class<T> clazz) { 
     try { 
      return clazz.cast(hashMap.get(o)); 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 

    @Override 
    public Object getSomething(Object s) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

} 

在主类上述变化之后予encouted投误差的方法rtConvert.convertInstanceOfObject(“S”,String.class)的每个调用错误消息的类型:

Incompatible types: Object cannot be converted to String. 

如果我尝试运行主体,我会得到:线程“main”中的异常java.lang.RuntimeException:不可编译的源代码 - 不兼容的类型:java.lang.Object不能转换为java.lang.String

+0

类型删除。 Java泛型不像C++模板:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html – duffymo

+3

您好cparaskeva - 你可以编辑你的问题,包括更多的细节如何以及它不编译? –

+5

如果出现错误,请始终包含错误消息。 – Thilo

回答

1

它可能是Java试图引用泛型类型的一个问题。如果您在主要方法中指定rtConvert变量的泛型类型,则可以解决此问题:IRuntimeConvert<Object> rtConvert,而不仅仅是IRuntimeConvert rtConvert

默认情况下,我总是尝试指定泛型变量类型。

+0

是的,谢谢你,这是问题!不过,我认为,默认情况下,Java正在将未绑定类型替换为对象 – cparaskeva

3

这是因为您已在执行中指定的通用类型为Object与以下行:

public class RuntimeConvertImpl implements IRuntimeConvert<Object> { 

因此,为了getSomething通话将总是要返回一个Object。然而,由于StringObject一个子类,这不能被自动转换为String,你必须做一些事情,如:

String s = (String) rtConvert.getSomething(); 

请注意,这并不能保证类型安全,并可能导致ClassCastException小号。

+0

如果您想使用泛型...请使用它们!如果你想要返回一个字符串对象只是instanciate它:IRuntimeConvert rtConvert 但是,作为这个答案解释的问题,我投它 – loicmathieu

+0

谢谢tou for you解释!事实上,我对仿制药产生了怀疑。 – cparaskeva

+0

据我所知,在main()方法中没有'getSomething()'。因此在这里没有编译错误。 –

2

我无法为您编写Java语言规范。我只是得出一些结论。

如果更改main()一行:

IRuntimeConvert<?> rtConvert = new RuntimeConvertImpl(hashMap); 
//  type ^^^^ 

然后main()将编译。因此,显然javac需要全部要为实际对象类型定义的泛型。然后它可以处理方法级通用参数。

+0

我已经给出了这个答案。 –

+0

这发生在并行编辑。反正也是+1。 –