Java 必需的类型T,提供的对象

Java 必需的类型T,提供的对象,java,Java,我尝试实现通用链表,但出现错误: 所需类型T,行T val=head.val中提供的对象 DDLinkedList类: public class DDLinkedList <T>{ private ListElement head; private ListElement tail; protected <T> void addToHead(T val){ if (this.isEmpty()){ head = new ListElement(v

我尝试实现通用链表,但出现错误:

所需类型T,行T val=head.val中提供的对象

DDLinkedList类:

public class DDLinkedList <T>{
private ListElement head;
private ListElement tail;

protected <T> void addToHead(T val){
    if (this.isEmpty()){
        head = new ListElement(val,head);
        tail = head;
    }else {
        head = new ListElement(val, head);
        head.next.prev  = head;
    }
}

protected <T> T removeFromHead(){
    if(this.isEmpty()){
        return null;
    }
    T val = head.val;
    head = head.next;
    return val;
}
}
公共类DDLinkedList{
私营部门主管;
私家车尾;
受保护的无效添加头(T val){
if(this.isEmpty()){
head=新列表元素(val,head);
尾=头;
}否则{
head=新列表元素(val,head);
head.next.prev=头;
}
}
受保护的T从头部移除(){
if(this.isEmpty()){
返回null;
}
T val=head.val;
head=head.next;
返回val;
}
}
列表元素类:

public static class ListElement<T> {
    private ListElement next;
    private ListElement prev;
    private T val;

    public ListElement(){
        this(null, null, null);
    }

    public ListElement(T val){
        this(val, null, null);
    }


    public ListElement(T val, ListElement next, ListElement prev){
        this.val = val;
        this.next = next;
        this.prev = prev;

    }

}
公共静态类ListElement{
其次是私人列表;
私人上市公司;
私人旅行社;
公共列表元素(){
这个(空,空,空);
}
公共列表元素(T val){
这(val,null,null);
}
公共ListElement(T val、ListElement next、ListElement prev){
this.val=val;
this.next=next;
this.prev=prev;
}
}

可能是什么问题?

导致此错误的原因是您在
removeFromHead()
中重新声明了类型
T
T
已经在类声明中声明,因此编译器试图将相同名称的两种不同类型等同起来

将方法重新声明为:
protected T removeFromHead()
,该错误应消失。(在另一个类方法中也存在同样的问题。)


正如评论者所指出的,您还错过了类型参数
T
关闭
liselement
声明中所有出现的
liselement
,这将生成单独的警告。

更改以下行

private ListElement<T> head;
private ListElement<T> tail;
私有列表元素头;
私家车尾;

让我们看看您的代码(以及我建议的有关泛型的更改):

不要使用
受保护的void addToHead(t val){
,因为
引入了一种新的变量类型,顺便说一句,也称为
t
,但与预期的列表元素类型
t
无关

        if (this.isEmpty()){
            head = new ListElement<T>(val, head, null);
    private T val;

    public ListElement(){
        this(null, null, null);
    }

    public ListElement(T val){
        this(val, null, null);
    }

    public ListElement(T val, ListElement<T> next, ListElement<T> prev){
        this.val = val;
        this.next = next;
        this.prev = prev;

    }
}
由于声明了
private liselement head;
,编译器现在知道
head.val
属于
T

        head = head.next;
        return val;
    }
}

public static class ListElement<T> {
    private ListElement<T> next;
    private ListElement<T> prev;

还有一个问题是,您在
liselement
中有私有字段,但从外部访问它们。解决方案是保持字段私有,为字段引入getter和setter,并使用getter和setter而不是直接访问字段。或者更好的是,将链接逻辑移到
liselement类,因此您根本不需要设置器。

当您声明
next
prev
时,您还会收到关于使用原始类型的警告。注意警告。原始使用参数化类“liselement”是否回答了您的问题?
            tail = head;
        }else {
            head = new ListElement<T>(val, head, null);
            head.next.prev  = head;
        }
    }
    
    protected T removeFromHead(){
        if(this.isEmpty()){
            return null;
        }
        T val = head.val;
        head = head.next;
        return val;
    }
}

public static class ListElement<T> {
    private ListElement<T> next;
    private ListElement<T> prev;
    private T val;

    public ListElement(){
        this(null, null, null);
    }

    public ListElement(T val){
        this(val, null, null);
    }

    public ListElement(T val, ListElement<T> next, ListElement<T> prev){
        this.val = val;
        this.next = next;
        this.prev = prev;

    }
}