为什么JAVA在接口中使用泛型类型时无法编译

时间:2016-08-18 11:57:05

标签: java generics

您好我在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."); 
    }

}

在主类中进行上述更改后,我为每次调用方法rtConvert.convertInstanceOfObject(“s”,String.class)时出现了类型转换错误,并显示错误消息:

Incompatible types: Object cannot be converted to String.

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

3 个答案:

答案 0 :(得分:3)

这是因为您已使用以下行将实现中的泛型类型指定为getSomething

Object

因此,对String的调用始终必须返回Object。但是,由于StringString s = (String) rtConvert.getSomething(); 的子类,因此无法自动转换为ClassCastException,您必须执行以下操作:

show()

请注意,这并不能保证类型安全,可能会导致AlertDialog.Builder adb = new AlertDialog.Builder(YourActivity.this); //...code to add methods setPositive an setNegative buttons s。

答案 1 :(得分:2)

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

如果您更改main()中的一行:

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

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

答案 2 :(得分:1)

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

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