通用:ArrayList 的?在 Java 中扩展 ISomeInterface | 珊瑚贝

Generic: ArrayList of ? Extends ISomeInterface in Java


我在下面的代码中遇到了一些问题。

1
2
3
4
5
6
public ArrayList<? extends IEvent> getEventsByDateRange(DateTime minStartTime,  DateTime minEndTime)
{
    ArrayList<? extends IEvent> returnedEvents = new ArrayList<GoogleEvent>();
    returnedEvents.add(new GoogleEvent());
    return (returnedEvents);
}

这会为”returnedEvents.add(new GoogleEvent()); line of code”返回以下编译错误:

The method add(capture#1-of ? extends IEvent) in the type
ArrayList is not applicable for the
arguments (GoogleEvent)

类GoogleEvent的声明如下:

1
public class GoogleEvent implements IEvent {}

我知道在 Java 中使用泛型有一些棘手的部分,因此是通配符,但我似乎无法弄清楚这一点。

谢谢。


你为什么不写:

1
2
3
4
5
6
public List<IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime)
{
    List<IEvent> returnedEvents = new ArrayList<IEvent>();
    returnedEvents.add(new GoogleEvent());
    return returnedEvents;
}

  • ArrayList<GoogleEvent> 与 List<IEvent> 的赋值不兼容。
  • 您不能将 ArrayList<GoogleEvent> 分配给 List<IEvent>。
  • 你不能这样做..它不是同一个对象类型
  • 对不起,我忘了替换泛型参数
  • 现在你有一个问题,因为你不能创建 IEvents 的实例,它是一个接口
  • @Mortalus:为什么不呢?你可以,它是一个泛型列表,而不是一个数组。我什至试过:)


解决办法:

1
ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();

您的错误原因是因为编译器正在尝试进行捕获转换。

在您的情况下,returnedEvents 捕获了一些扩展 IEvent 的未知数(即扩展/实现 IEvent 的任何内容)并且您将其分配给参数化类型 GoogleEvent)。

编译器看到,returnedEvents.add(? extends IEvent) 没有使用 returnedEvents.add(GoogleEvent) 的签名进行验证,因为捕获占位符设置在 returnedEvents 上。

  • 这不编译。您不能在通用实例化中使用通配符。
  • @John B,谢谢,我看到了,页面需要很长时间才能更新。我已经更新了我的帖子。


您不需要使用 ? extends IEvent,因为仅使用 IEvent,Java 将动态绑定 GoogleEvent 类。它是多态性。


这是不允许的。 returnedEvents 包含 GoogleEvent 对象的列表,不得允许接受不是 GoogleEvent 对象的对象。

虽然在您的示例中您恰好传递了一个 GoogleEvent,但您是通过调用一个接受任何实现 IEvent 的 add 版本来实现的。根本不允许调用该 add 方法,因为它可能导致列表存储 GoogleEvent.

以外的内容

Java 通配符”编辑出”方法会以这种方式破坏规则。

如果你需要返回那个通配符列表类型,一个 ArrayList<GoogleEvent> 就可以满足它。

注意这是一个完整的源文件,编译时不会出错:

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.*;

interface IEvent { }

class GoogleEvent implements IEvent { }

public class Foo {
    public ArrayList<? extends IEvent> getEventsByDateRange()  {
        ArrayList<GoogleEvent> returnedEvents = new ArrayList<GoogleEvent>();
        returnedEvents.add(new GoogleEvent());
        return (returnedEvents);
    }
}

  • 我应该如何将 googleEvents 类的对象添加到实现 IEvents 的对象数组列表中?
  • 再次在返回语句中,我得到 Type mismatch: cannot convert from List<GoogleEvent> to ArrayList<?扩展 IEvent>
  • List 还是 ArrayList?他们不一样。
  • @Mortalus – 查看进一步更新,一个完整的源文件,您可以尝试编译。
  • 谢谢 !!!!!完美地工作..所以现在我应该能够使用 IEvent 接口访问所有糟糕的 GoogleEvents 了吗?
  • 是的,Java 泛型将允许对可以从 ArrayList<? extends IEvent> 检索的对象调用 IEvent 方法。 (但如前所述,您将不被允许向集合中添加新对象。)


你不能写入一个用 ? extends … 声明的变量。仅在使用 ? super ….

时才允许写入

这可以用下面的例子来解释:

1
2
3
4
5
6
7
8
9
List<GoogleEvent> googleEvents = new ArrayList<GoogleEvent>();
ArrayList<? extends IEvent> returnedEvents = googleEvents;

// Would be OK
returnedEvents.add(new GooleEvent());

// Would be OK to the definition of returnedEvents,
// but breaks the googleEvents.
returnedEvents.add(new OtherEvent());


您的简短解决方案是将 returnedEvents 声明为 List<GoogleEvent>.

  • 这将返回类型不匹配:无法从 List<GoogleEvent> 转换为 ArrayList<?扩展 IEvent>
  • 使用列表<?扩展 IEvent> 作为结果类型。通常哪个更好,因为您可以将 ArrayList 更改为另一个列表,例如。 g.、LinkedList不改变操作界面。
  • 添加演员表 ArrayList<? extends IEvent> returnedEvents = (ArrayList<? extends IEvent>)googleEvents;


1
2
3
4
5
6
7
public ArrayList<IEvent> getEventsByDateRange(DateTime minStartTime,
        DateTime minEndTime)
{
    ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();
    returnedEvents.add(new GoogleEvent());
    return (returnedEvents);
}

来源:https://www.codenong.com/7821064/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9926.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?