实例化类型 的通用类

发布于 2024-12-23 12:55:00 字数 484 浏览 1 评论 0 原文

我正在学习 SCJP/OCPJP,我遇到了一个对我来说很奇怪的示例问题。

示例代码实例化了两个通用集合:

List<?> list = new ArrayList<?>();
List<? extends Object> list2 = new ArrayList<? extends Object>();

问题的“正确”答案是该代码可以编译,但添加到任一集合都会产生运行时错误。

当我尝试编译这样的代码时,我只会收到错误。 Java 教程甚至没有显示这种类型的代码,它通常使用通配符作为向上转换的一部分。

Collection<?> c = new ArrayList<String>();

上面的两个通用集合是合法代码吗?按照我的逻辑,第二个只会禁止接口。第一个看起来完全没用。为什么要使用不尝试控制的仿制药?

I'm studying for the SCJP/OCPJP and I came across a sample question that seams strange to me.

The sample code instantiated two generic collections:

List<?> list = new ArrayList<?>();
List<? extends Object> list2 = new ArrayList<? extends Object>();

The "correct" answer to the question was that this code would compile but adding to either collection would produce a runtime error.

When I try to compile code like this I just get errors. The Java tutorial does not even show this type of code, it instead usually uses wildcards as a part of an upcast.

Collection<?> c = new ArrayList<String>();

Are the two generic collections above even legitimate code? The second by my logic would only disallow interfaces. The first one looks completely useless. Why use a generic that makes no attempt at control?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

对你的占有欲 2024-12-30 12:55:00

看看优秀的Java 泛型教程 PDF。更具体地说,有关通配符的部分包含您问题的答案,我引用

Collection<?> c = new ArrayList<String>();
c.add( new Object() );

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

Check out the excellent Java generics tutorial PDF. More specifically the section about wildcards contains the answer to your question, and I quote

Collection<?> c = new ArrayList<String>();
c.add( new Object() );

Since we don’t know what the element type of c stands for, we cannot
add objects to it. The add() method takes arguments of type E, the
element type of the collection. When the actual type parameter is ?,
it stands for some unknown type. Any parameter we pass to add would
have to be a subtype of this unknown type. Since we don’t know what
type that is, we cannot pass anything in. The sole exception is null,
which is a member of every type.

随梦而飞# 2024-12-30 12:55:00

如果你想在运行时声明 Type,你可以这样做:

public class Clazz1<T> {

private final List<T> list = new ArrayList<T>();

private List<T> getList() {
    return list;
}

/**
 * @param args
 */
public static void main(String[] args) {
    Clazz1<Integer> clazzInt = new Clazz1<Integer>();
    clazzInt.getList().add(2);
    System.out.println(clazzInt.getList());

    Clazz1<String> clazzString = new Clazz1<String>();
    clazzString.getList().add("test");
    System.out.println(clazzString.getList());
}

}

If you want to declare Type at runtime, you can do something like this:

public class Clazz1<T> {

private final List<T> list = new ArrayList<T>();

private List<T> getList() {
    return list;
}

/**
 * @param args
 */
public static void main(String[] args) {
    Clazz1<Integer> clazzInt = new Clazz1<Integer>();
    clazzInt.getList().add(2);
    System.out.println(clazzInt.getList());

    Clazz1<String> clazzString = new Clazz1<String>();
    clazzString.getList().add("test");
    System.out.println(clazzString.getList());
}

}
总攻大人 2024-12-30 12:55:00

我之前在这个答案中回答过这个问题。 ? 不能在实例化中使用。我不知道为什么它说代码可以编译,我使用过的 java 编译器都不允许这样做。您可以通过以下方式执行上面显示的操作:

List<?> list = new ArrayList();

这将编译并运行,但您不能这样做:

list.add("hello world"); //This wouldn't compile

I answered this somewhat before in this answer. ? cannot be used in the instantiation. I'm not sure why it says the code would compile, none of the java compilers I have used would allow that. You could do what is shown above by the following:

List<?> list = new ArrayList();

That would compile and run, but you couldn't do:

list.add("hello world"); //This wouldn't compile
迷爱 2024-12-30 12:55:00

new 生成对象的具体实例。具体实例只能有一种类型,包括任何泛型。知道这一点后,通配符就不能与 new 一起使用。

new produces a concrete instance of an object. The concrete instance can have only one type, including any generics. Knowing this, wildcards cannot work with new.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文