泛型Java 1.7中的菱形-如何在1.6中为Java编译器编写

泛型Java 1.7中的菱形-如何在1.6中为Java编译器编写,java,generics,Java,Generics,如果不能使用菱形,如何为Java 1.6编译器编写Java 1.7代码 例如: private ReplacableTree<E> convertToIntended(Tree<? extends E> from,ReplacableTree<E> to) { TreeIterator<? extends E> it = new TreeIterator<>(from.getRoot()); while(it.has

如果不能使用菱形,如何为Java 1.6编译器编写Java 1.7代码

例如:

private ReplacableTree<E> convertToIntended(Tree<? extends E> from,ReplacableTree<E> to) {

    TreeIterator<? extends E> it = new TreeIterator<>(from.getRoot());

    while(it.hasNext()) {
        E e = it.next().getElem();
        to.add(e);
    }
    return to;
}


public class TreeIterator<E> implements TreeIter<Node<E>> {
....
}
不允许写

TreeIterator<? extends E> it = new TreeIterator<?>(from.getRoot());
TreeIterator<? extends E> it = new TreeIterator<E>(from.getRoot());
TreeIterator<? extends E> it = new TreeIterator<? extends E>(from.getRoot());

尤其是第三个对我来说很困惑。为什么不起作用?我只想从一棵树中读取元素,这棵树可能是一个子类型树,当它在一棵新树中包含E类型的元素时。

简而言之,你不需要为Java 6编译器编写Java 7代码,你必须使用旧的、重复的非菱形语法。不,您不能在源代码1.7中指定1.6的目标,它将不起作用

简而言之,您不需要为Java 6编译器编写Java 7代码-您必须使用旧的、重复的非菱形语法。不,您不能在源代码1.7中指定1.6的目标,它将不起作用

通配符类型不允许作为以下类型中的类型参数:

如果类实例创建表达式中使用的任何类型参数是通配符类型参数§4.5.1,则为编译时错误

因此,第一个和第三个变体无效


变量2无效,因为TreeInterator构造函数需要一个节点,但您为它指定了一个节点通配符类型不允许作为以下中的类型参数:

如果类实例创建表达式中使用的任何类型参数是通配符类型参数§4.5.1,则为编译时错误

因此,第一个和第三个变体无效


变量2无效,因为TreeIterator构造函数需要一个节点,但是您给它一个节点meriton已经很好地解释过了。我只是想建议您也可以不使用通配符声明:

TreeIterator<E> it = new TreeIterator<E>(from.getRoot());

梅里顿已经解释得很好了。我只是想建议您也可以不使用通配符声明:

TreeIterator<E> it = new TreeIterator<E>(from.getRoot());
通常,表示只使用与左侧声明中相同的类型参数。但在本例中,该声明是一个通配符

使用通配符类型参数new TreeIterator构造构造函数没有意义,通常意味着只使用与左侧声明中相同的类型参数。但在本例中,该声明是一个通配符


使用通配符类型参数new TreeIterator创建构造函数是没有意义的我知道这是一个老问题,但如果有人无意中发现了这个问题,我会认为最明显的编写方法是:

private <U extends E> ReplaceableTree<E> convertToIntended(Tree<U> from, ReplaceableTree<E> to)
{
    TreeIterator<U> it = new TreeIterator<U>(from.getRoot());

    while(it.hasNext())
    {
        E e = it.next().getElem();
        to.add(e);
    }

    return to;
}

我不认为这样的更改会破坏现有代码,因为从现有签名到此签名的类型约束是相同的。

我知道这是一个老问题,但如果有人无意中发现了这一点,我会认为最明显的编写方法是:

private <U extends E> ReplaceableTree<E> convertToIntended(Tree<U> from, ReplaceableTree<E> to)
{
    TreeIterator<U> it = new TreeIterator<U>(from.getRoot());

    while(it.hasNext())
    {
        E e = it.next().getElem();
        to.add(e);
    }

    return to;
}

我不认为这样的更改会破坏现有代码,因为从现有签名到这个签名的类型约束是相同的。

第三个在语法上是正确的,但如果没有getRoot和TreeIterator构造函数的签名,我无法找出问题所在。第三个在语法上是不正确的。请不要在评论中发布答案。。第二个问题是关于getRoot和TreeIterator构造函数的签名。getRoot:node和Tree Iterator构造函数:TreeIterator节点{this.head=node;this.current=head;start=false;}@meriton哦,对了,实例化对象时不能使用通配符。第三个是语法正确的,但是如果没有getRoot和TreeIterator构造函数的签名,我就无法找出问题所在。第三个在语法上是不正确的。请不要在评论中发布答案。。第二个问题是关于getRoot和TreeIterator构造函数的签名。getRoot:node和树迭代器构造函数:TreeIterator节点{this.head=node;this.current=head;start=false;}@meriton哦,对,实例化对象时不能使用通配符。TreeIterator的contstructor参数类型为Node。因此,Node的构造函数参数是E。在编写变量2时,eclipse说:构造函数TreeIteratorNode未定义这意味着什么?TreeIterator的contstructor参数类型是Node。因此,节点的构造函数参数是E。在编写变量2时,eclipse说:构造函数TreeInteratorNode未定义这意味着什么?这将需要更改ConvertToIntented的方法签名,以将其声明为具有类型树。我们不知道在那之后调用方是否还会编译。@meriton:你为什么认为需要更改签名?我只是尝试了一个简单的例子,它只对不同的类进行相同的转换{List test collection区别在于ArrayList的构造函数将其参数声明为CollectionType,这将需要将ConvertToIntented的方法签名更改为Declared from,以将其声明为具有类型树。我们不知道调用方是否仍会编译
在那之后。@meriton:你为什么认为需要更改签名?我刚刚尝试了一个简单的示例,它只对不同的类进行相同的转换类Test{List Test Collection区别在于ArrayList的构造函数将其参数声明为Collection类型