【问题标题】:Why does this class behave differently when I don't supply a generic type?为什么当我不提供泛型类型时,此类的行为会有所不同?
【发布时间】:2013-04-01 06:42:31
【问题描述】:

我不明白为什么这会让编译器感到困惑。我使用泛型类型T 来保存与putget 方法无关的对象。我一直认为GenericClassGenericClass<Object> 在功能上是相同的,但我一定是误会了。编译DoesntWork 类时,我得到incompatible types - required: String - found: ObjectWorks 类符合我的预期。这是怎么回事?

public class GenericClass<T> {
    public <V> void put(Class<V> key, V value) {
        // put into map
    }

    public <V> V get(Class<V> key) {
        // get from map
        return null;
    }

    public static class DoesntWork {
        public DoesntWork() {
            GenericClass genericClass = new GenericClass();
            String s = genericClass.get(String.class);
        }
    }

    public static class Works {
        public Works() {
            GenericClass<Object> genericClass = new GenericClass<Object>();
            String s = genericClass.get(String.class);
        }
    }
}

【问题讨论】:

  • genericClass 更接近genericClass&lt;?&gt; 而不是genericClass&lt;Object&gt;
  • 话虽如此,我不明白为什么DoesntWork 不应该工作。
  • 尝试强制类型:genericClass.&lt;String&gt;get(String.class)(不确定语法是否正确)

标签: java generics


【解决方案1】:

关于原始类型如何工作的事情——你已经省略了参数的泛型类型——是它们的所有泛型以及它们的方法也被删除了。所以对于原始的GenericClassgetput 方法失去了它们的泛型。

【讨论】:

  • 为了兼容性,使用原始类型本质上表明您正在使用旧的、预泛型代码;围绕原始类型的大多数奇怪之处都是出于兼容性目的的黑客攻击。 JLS 4.8 有更多详情。
  • 但是对于为什么这种特定行为是必要的示例,请考虑以下示例:使用 Java 1.4 构建的遗留代码必须从 Java 1.4 的 List 获得相同的行为 -- 前泛型 - - 以及来自 Java 5 的 List,它被重写以引入泛型。这很尴尬,但对于向后兼容来说是必要的——但它不应该成为新代码的问题,因为新代码基本上不应该使用原始类型。
  • “新代码基本上不应该使用原始类型”——我同意这一点。
  • 所以如果我在处理对象时不知道类型,我应该使用??例如:带有洗涤装饰器的车辆应该使用wash(Vehicle&lt;?&gt; vehicle)而不是wash(Vehicle vehicle)
【解决方案2】:

这是因为当您使用没有额外类型信息的泛型类时,您使用的是有时称为类的degenerate 形式。 degenerate 表单已删除所有泛型类型信息。

基本上 - 你的课程变成这样:

public class GenericClass {
    public void put(Class key, Object value) {
        // put into map
    }

    public Object get(Class key) {
        // get from map
        return null;
    }

    ...
}

因此,您看到的编译器响应是预期行为。

Java Puzzlers 中提到了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    相关资源
    最近更新 更多