无法推断泛型类的类型参数

ukqbszuj  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(394)

我正在尝试使用后缀表达式创建表达式树。这需要一个可以容纳树对象的堆栈。我创建了一个泛型堆栈类 <TreeTemp> 作为类型参数。
在尝试用下面的语句初始化堆栈时,给出“cannot inferse type arguments for treestack<>”错误。 private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp()); 堆栈类:

public class TreeStack<T> {

    private T [] stackElem;
    private final int MAXSTACKSIZE;
    private int top;

    public TreeStack(Class<T> t) {
        top = -1;
        MAXSTACKSIZE = 20;
        final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
        this.stackElem = stackElem;

    }

    public void push(T elem) throws Exception{
        if(isFull()) {
            stackElem[++top] = elem;
        }
        else
            throw new Exception("Stack is already Full");
    }

    public T pop() throws Exception {

        if(isEmpty()) {
            return stackElem[top--];
        }
        else

            throw new Exception("Stack is Empty");
    }

    public boolean isEmpty() {return top == -1;}

    public boolean isFull() {return top==MAXSTACKSIZE-1;}
}

类(具有创建树的方法的类)

public class PostFix {

    private String expression = new String("A*B+C");
    private char [] expElem = expression.toCharArray();
/*Error on below Statement*/

    private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());

    public TreeTemp makeTree() throws Throwable {
        try {
        for(int i=0;i<expElem.length;i++) {
            ExpNode eNode = new ExpNode();
            eNode.setiData(expElem[i]);
            TreeTemp t = new TreeTemp();
            t.setRoot(eNode);
            if(!Character.isLetter(expElem[i])) {
                t.setLeftTree(stack1.pop());
                t.setRightTree(stack1.pop());   
                }
            stack1.push(t);
        }
        return stack1.pop();
        }catch (Exception e) {
            throw new Exception("Stack Error while creating a Tree", e);
        }
    }

    public static void main(String[] args) throws Throwable {
        PostFix pf = new PostFix();
        TreeTemp t = pf.makeTree();

    }

树类(要添加到堆栈中的类型):

public class TreeTemp {

    private ExpNode root;
    private TreeTemp leftTree;
    private TreeTemp rightTree;

    /*public TreeTemp(ExpNode expNode) {
        root = expNode;

        }*/

    public TreeTemp getLeftTree() {
        return leftTree;
    }

    public void setLeftTree(TreeTemp leftTree) {
        this.leftTree = leftTree;
    }

    public TreeTemp getRightTree() {
        return rightTree;
    }

    public void setRightTree(TreeTemp rightTree) {
        this.rightTree = rightTree;
    }

    public ExpNode getRoot() {
        return root;
    }
    public void setRoot(ExpNode node) {
        this.root = node;
    }
}

有人能给点建议吗。

clj7thdc

clj7thdc1#

你的 TreeStack 只有一个构造函数。在这里:

public TreeStack(Class<T> t) {

因此,要调用它,需要传递表示与t类型关联的类的class对象。所以,类本身,而不是“t的某个特定示例”。当您在错误线路上呼叫时:

private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());

您正在传递treetemp的一个示例。而不是“treetemp,class”这个概念。尝试 new TreeStack<>(TreeTemp.class); 请注意,作为一般规则,传递 Class<T> 是一种代码气味;您正试图使泛型成为它所没有的东西(您正在尝试运行时具体化)。这在客观上是不好的:它意味着你不能做出决定 TreeStack<List<String>> 例如,因为您被限制在泛型和 j.l.Class 示例可以表示事物,这只是简单的、非泛型的、非原语类。 final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE); 看起来您想要该类的唯一原因是确保数组的类型正确。
这不是必须的。做一个新的 Object[] 数组,并在需要返回t的任何时候向t施放。现在您的treestack构造函数完全不需要参数。
检查java.util.arraylist的源代码,与此评估结果一致;它由对象数组支持,而不是t[]。

guykilcj

guykilcj2#

这个 TreeStack 构造函数接受 Class<T> ,不是 T ,所以您应该:

new TreeStack<>(TreeTemp.class);

因为这是一个创建表达式树的练习,所以实际上不需要从头开始实现堆栈。你应该用 ArrayDeque 通过 Deque java集合api中的接口。

private Deque<TreeTemp> stack1 = new ArrayDeque<>();
``` `Deque` 你所有的方法 `TreeStack` 有,还有更多。

相关问题