泛型编译问题:不兼容的类型 [英] Generics compile issue: incompatible types

查看:491
本文介绍了泛型编译问题:不兼容的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定这个简单的类:

  import java.util.Collection; 

public class GenericTest< T> {
public Collection< String> getKeys(){
返回null;

public void copy(GenericTest a_from){
for(String x:a_from.getKeys()){



}

我收到以下编译错误,但不明白为什么。

 错误:不兼容类型
for(String x:a_from.getKeys()){
required:String
found:Object

如果我将参数更改为copy()方法为GenericTest< ; T>,但那不是我想要的。 copy()方法在任何类型的GenericTest上都是有效的,而不仅仅是GenericTest< T>

解决方案

创建一个通用类。如果您使用泛型类的原始类型,则在类中使用的所有参数化类型都会丢失其类型信息。因此,对于 GenericTest 原始类型, getKeys()方法签名更改为:

  public Collection getKeys(){
return null; (

所以,如果迭代 getKeys() GenericTest 原始类型的方法,您将获得 Object ,而不是 String ,我不明白你为什么期望。



From JLS第4.8节 - 原始类型


未继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型它的超类或超级接口是对应于在对应于C的泛型声明中删除其类型的原始类型。







您应该在方法中真正使用 GenericTest< T> 作为参数类型,而不是原始类型。并将 getKeys 的返回类型更改为 Collection< T>



将您的课程更改为:

  public class GenericTest< T> {
public Collection< T> getKeys(){
返回null; (T x:a_from.getKeys()){

}
}的公共无效拷贝(GenericTest< T> a_from){
}

类型 T 是从您为此泛型类创建的参数化类型中产生的。对于 GenericTest< String> T 将被作为字符串,在您的课程中。






参考:


Given this simple class:

    import java.util.Collection;

    public class GenericTest<T> {
      public Collection<String> getKeys() {
        return null;
      }
      public void copy(GenericTest a_from) {
        for (String x : a_from.getKeys()) {

        }
      }
    }

I am getting the following compile error, but don't understand why.

    error: incompatible types
    for (String x : a_from.getKeys()) {
      required: String
      found:    Object

The error goes away if I change the parameter to the copy() method to GenericTest<T>, but that is not what I want. The copy() method is valid on any type of GenericTest, not just GenericTest<T>.

解决方案

This is not how you create a generic class. If you use a raw type of your generic class, then all the parameterized type used inside the class, loose their type information. So, for GenericTest raw type, the getKeys() method signature changes to:

public Collection getKeys() {
    return null;
}

So, if you iterate over getKeys() method of GenericTest raw type, you will get Object, and not String, which I don't see why you expect.

From JLS Section 4.8 - Raw Types:

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.


You should really use GenericTest<T> as parameter type in your method, instead of raw type. And change the return type of getKeys to Collection<T>.

Change your class to:

public class GenericTest<T> {
    public Collection<T> getKeys() {
      return null;
    }
    public void copy(GenericTest<T> a_from) {
      for (T x : a_from.getKeys()) {

      }
   }
}

The type T is infered from the parameterized type you create for this generic class. For GenericTest<String>, T will be infered as String, in your class.


Reference:

这篇关于泛型编译问题:不兼容的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆