【问题标题】:Generics in Java, using wildcardsJava中的泛型,使用通配符
【发布时间】:2009-02-02 16:01:33
【问题描述】:

我有一个关于 Java 泛型的问题,即使用通配符。我有一个像这样的示例类 GenClass:

public class GenClass<E> {

    private E var;

    public void setVar(E x) {
        var = x;
    }

    public E getVar() {
        return var;
    }
}

我还有一个简单的类:

public class ExampleClass {

}

我已经编写了以下测试类:

public class TestGenClass {

    public static void main(String[] str) {

        ExampleClass ec = new ExampleClass();

        GenClass<ExampleClass> c = new GenClass<ExampleClass>();

        c.setVar(ec);
        System.out.println(c.getVar());  // OUTPUT: ExampleClass@addbf1
    }

}

现在,如果我使用通配符并在测试类中这样写:

GenClass<?> c = new GenClass<ExampleClass>();

在:

GenClass<ExampleClass> c = new GenClass<ExampleClass>();

编译器对这个新语句没有问题,但是它抱怨

c.setVar(ec);

它说“方法 (setVar()) 不适用于参数 (ExampleClass)”。为什么我会收到此消息?

我认为我使用通配符的方式使引用变量 c 的类型为 GenClass,它可以接受任何类作为参数 - 在 E 的位置上,我将拥有任何类。这只是变量的声明。然后我用

初始化它
new GenClass<ExampleClass>()

这意味着我创建了一个 GenClass 类型的对象,它有一个 ExampleClass 类型的类作为参数。所以,我认为现在 GenClass 中的 E 将是 ExampleClass,我将能够使用方法 setVar(),将其作为参数类型为 ExampleClass。 这是我的假设和理解,但Java似乎不喜欢它,我也不对。 感谢您的任何评论,谢谢。

【问题讨论】:

  • 根据您的用户历史记录,您从未接受过答案。你觉得你现在可以开始了吗?您甚至可以从交易中获得 2 个代表点和一个免费徽章(第一次)。 :D

标签: java generics bounded-wildcard


【解决方案1】:

Java Generics Tutorial 涵盖了这种确切情况。

请注意,[使用通配符],我们仍然可以从 [通用 Collection] 中读取元素并为它们输入 Object。这总是安全的,因为无论集合的实际类型是什么,它都包含对象。但是,向其中添加任意对象是不安全的:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error

由于我们不知道c 的元素类型代表什么,我们无法向其中添加对象。 add() 方法接受 E 类型的参数,即集合的元素类型。当实际类型参数为? 时,它代表某种未知类型。 我们传递给add 的任何参数都必须是这个未知类型的子类型。因为我们不知道那是什么类型,所以我们不能传入任何东西。唯一的例外是null,它是每个类型的成员。

(强调我的)

【讨论】:

    【解决方案2】:

    mmyers 有正确的答案,但我只是想评论您问题的这一部分(这听起来像是您想要使用通配符的理由):

    我认为我使用通配符的方式使引用变量 c 的类型为 GenClass,它可以接受任何类作为参数 - 在 E 的位置上,我将拥有任何类。这只是变量的声明。然后我用

    初始化它

    如果你真的想做到这一点,你可以做一些没有编译错误的事情:

    GenClass<Object> gc = new GenClass<Object>();
    gc.setVar(new ExampleClass());
    

    但话又说回来,如果你想声明一个可以包含任何类型的GenClass 实例,我不确定你为什么要使用泛型——你可以只使用原始类:

    GenClass raw = new GenClass();
    raw.setVar(new ExampleClass());
    raw.setVar("this runs ok");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 2011-11-12
      相关资源
      最近更新 更多