与集合和泛型相关的 Java 10 迁移问题



继续我之前在链接中的查询:Java 10 上的 Swing 问题,我发现了更多问题(仅突出显示错误),这次我看到问题主要在迁移到 java 10 后的集合 API 中。

下面是错误。想知道从 Java 8 迁移时 Java 10 是否有任何重大变化(从集合/泛型的角度来看)。

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmuitreeWMTreeNode.java:159: error: breadthFirstEnumeration() in WMTreeNode cannot override breadthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends WMTreeNode> breadthFirstEnumeration() {
[javac]                                             ^
[javac]   return type Enumeration<? extends WMTreeNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmuitreeWMTreeNode.java:158: error: method does not override or implement a method from a supertype
[javac]     @Override
[javac]     ^
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmuitreeWMTreeNode.java:164: error: depthFirstEnumeration() in WMTreeNode cannot override depthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends WMTreeNode> depthFirstEnumeration() {
[javac]                                             ^
[javac]   return type Enumeration<? extends WMTreeNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmuitreeWMTreeNode.java:163: error: method does not override or implement a method from a supertype
[javac]     @Override
[javac]     ^
[javac]                           ^
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmuitreeWMTreeNode.java:298: error: no suitable method found for sort(Vector<TreeNode>)
[javac]             Collections.sort(children);

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuiloadLoadNode.java:90: error: breadthFirstEnumeration() in LoadNode cannot override breadthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends LoadNode> breadthFirstEnumeration() {
[javac]                                           ^
[javac]   return type Enumeration<? extends LoadNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuiloadLoadNode.java:95: error: depthFirstEnumeration() in LoadNode cannot override depthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends LoadNode> depthFirstEnumeration() {

[javac]   where T is a type-variable:
[javac]     T extends Object declared in class Class
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmautomationplotCopyCountJobParameterDescriptor.java:113: error: incompatible types: Integer cannot be converted to CAP#1
[javac]             final boolean outOfRange = (model.getMinimum().compareTo(i) > 0) || (model.getMaximum().compareTo(i) < 0);
[javac]                                                                      ^
[javac]   where CAP#1 is a fresh type-variable:
[javac]     CAP#1 extends Object from capture of ?
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmautomationplotCopyCountJobParameterDescriptor.java:113: error: incompatible types: Integer cannot be converted to CAP#1
[javac]             final boolean outOfRange = (model.getMinimum().compareTo(i) > 0) || (model.getMaximum().compareTo(i) < 0);

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuiloadSnapshotLoadNode.java:48: error: breadthFirstEnumeration() in SnapshotLoadNode cannot override breadthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends SnapshotLoadNode> breadthFirstEnumeration() {
[javac]                                                   ^
[javac]   return type Enumeration<? extends SnapshotLoadNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuiloadSnapshotLoadNode.java:53: error: depthFirstEnumeration() in SnapshotLoadNode cannot override depthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends SnapshotLoadNode> depthFirstEnumeration() {

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuifavoritesFavoritesTreeNode.java:30: error: breadthFirstEnumeration() in FavoritesTreeNode cannot override breadthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends FavoritesTreeNode> breadthFirstEnumeration() {
[javac]                                                    ^
[javac]   return type Enumeration<? extends FavoritesTreeNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuifavoritesFavoritesTreeNode.java:35: error: depthFirstEnumeration() in FavoritesTreeNode cannot override depthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends FavoritesTreeNode> depthFirstEnumeration() {

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuisaveSaveNode.java:113: error: breadthFirstEnumeration() in SaveNode cannot override breadthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends SaveNode> breadthFirstEnumeration() {
[javac]                                           ^
[javac]   return type Enumeration<? extends SaveNode> is not compatible with Enumeration<TreeNode>
[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagersrccomosmdatamgmtuisaveSaveNode.java:118: error: depthFirstEnumeration() in SaveNode cannot override depthFirstEnumeration() in DefaultMutableTreeNode
[javac]     public Enumeration<?extends SaveNode> depthFirstEnumeration() {
[javac]                                           ^

[javac] C:WorkSpaceJAVA10oswmrel20.10_PatchesWorkManagerOSMWebServicessrcjavacomosmwebserviceslegacyutilMessageAttachmentHandler.java:76: error: cannot find symbol
[javac]                         attachment.setRawContent(new BufferedInputStream(new FileInputStream(file)),
[javac]              
^

WMTreeNode正在扩展javax.swing.tree.DefaultMutableTreeNode.

问题

如果您仔细比较 Java 8 和 10 之间的DefaultMutableTreeNode代码,您会发现返回类型是通用的:

// Java 8 uses `Enumeration` as a "raw type"
public Enumeration breadthFirstEnumeration() { /*...*/ }
// Java 10 uses `Enumeration` as intended: with a type parameter
public Enumeration<TreeNode> breadthFirstEnumeration() { /*...*/ }

你的代码是这样的:

public Enumeration<?extends SnapshotLoadNode> breadthFirstEnumeration() { /*...*/ }

您的代码在 Java 8 上编译,因为出于兼容性原因,可以将泛型添加到原始类型。虽然可能存在问题(实际上与下面相同),但无论如何原始类型都被认为是不安全的,因此这些是意料之中的。

它不再在Java 10上编译,因为原始API想要返回Enumeration<TreeNode>,但你的覆盖不会这样做。相反,它返回子类型的Enumeration。现在,对于Enumeration来说,这实际上不是问题,因为它是只读的(返回更具体的类型当然总是可以的),但编译器不知道(方法可以接受更具体的类型 - 那不行)。

要更详细地理解最后一个括号,请假设它是一个List<TreeNode>和一个List<SnapshotLoadNode>。然后,用作DefaultMutableTreeNode的 API 将返回一个列表,调用方可以将TreeNode-s 添加到该列表。但是您的类仍然认为它有一个子类型的列表,并且会得到类强制转换异常 - 不好。如果没有原始类型,这种缺乏类型安全性是不可接受的,因此编译器会抱怨。

解决方案

如果DefaultMutableTreeNode是我的代码,我会更改breadthFirstEnumeration以返回Enumeration<? extends TreeNode>(我不知道,为什么不是这样)。这将使您的代码编译。

由于这不是一个选项,因此看起来您必须这样做:

  • 松开更精确的类型信息,并将覆盖的返回类型更改为Enumeration<TreeNode>
  • 如果需要更精确的返回类型,请创建一个新方法:

    public Enumeration<?extends SnapshotLoadNode>
    breadthFirstEnumerationAsSnapshotLoadNode() { /*...*/ }
    

最新更新