泛型:在非静态上下文中引用类型参数时出错

时间:2015-04-21 11:36:32

标签: java generics

public class stackofints<Item>
{
    private static node topofstack=null;

    private static class node{
        Item item;
        node next;
    }

    public static void push(Item item){
        node oldtopofstack=topofstack;
        topofstack=new node();
        topofstack.item=item;
        topofstack.next=oldtopofstack;
    }
    public static int pop(){
        Item item=topofstack.item;
        topofstack=topofstack.next;
        return item;
    }
    public boolean isEmpty(){return topofstack==null;}
    public static Item size(){
        Item i=0;
        node iterate=topofstack;
        while(iterate!=null)
        {
            iterate=iterate.next;
            i++;
        }
        return i;
    }

    public static void main(String[] args)
    {
        push(1);
        push(2);
        push(3);
        System.out.println(size());

    }

}

在上面的代码中我试图使用泛型类型但是我得到了一个编译错误:

  

File: D:\Java Code\stackofints.java [line: 6]
  Error: non-static type variable Item cannot be referenced from a static context.

有人可以帮我解决这个问题。感谢

4 个答案:

答案 0 :(得分:1)

您的类声明了一个名为“Item”的类型变量。它不是类的名称,而只是一个占位符,允许stackofints类的实例用他们想要的任何类型替换它。

(作为旁注,将这些类型变量(“占位符”)命名为类似于它们是不好的样式,因为它很混乱。您应该将其命名为T而不是class stackofints<T>另外,请用Camel-case命名你的类,大写的第一个字母是:class StackOfInts<T>

例如,您可以拥有这些实例:

stackofints<Integer> foo = new stackofints<>();  // Here, "Item" = Integer
stackofints<String>  bar = new stackofints<>();  // Now,  "Item" = String

所以你看到“Item”的值特定于每个实例,而不是类本身。

现在,您尝试从静态字段引用此值。根据定义,静态字段属于类本身,而不属于特定实例。

这就是编译器抱怨的原因:你试图唯一地引用可以有多个值的东西。

答案 1 :(得分:0)

Java中的泛型!=模板,你无法在静态类中做你想做的事情。在运行期间,Item将被减少到Object,因此T中不能有MyType<T>的静态实例,并且在运行时期间不能有所述实例的解析(因为每T 1}}缩减为Object)。

解决方案:使所有实例化(非静态)和您的类型的单例。

答案 2 :(得分:0)

在编译时,泛型允许在实例化对象时插入类型,然后可以确保对象的所有未来使用都能正确使用该对象。

在泛型之前:列出myList = new ArrayList();                     整数i =(整数)myList.get(1);

使用泛型:列出myList = new ArrayList&lt;&gt;();                 整数i = myList.get(1);

没有泛型,运行时会有大量的转换和大量的ClassCastExceptions;对于泛型,你不会超过编译。

使用您的代码,您尝试在静态方法中使用泛型。但是,静态方法不需要对象实例化,因此没有上下文。我可以创建一个List,List,List,静态方法不知道使用哪个,因此它是非法的。

此外,这个类的设计,基本上只有静态方法,似乎很可疑,你可能想重新访问。

答案 3 :(得分:0)

首先,您收到的错误涉及尝试关联绑定到Item类的类型参数stackofints。此类型参数仅允许在非静态上下文中引用。您需要在node类中定义类型参数。这些名称应该不同,以避免混淆。

现在,您的代码存在一些问题。

  1. 您的topofstack变量应该是一个实例变量,因此不应将其声明为静态。
  2. 您的pushpopsize方法不应该是静态的,因为它们应该与stackofints对象的实例相关联。
  3. 您不在主方法中创建stackofints的实例。
  4. 您没有为node课程提供通用类型。
  5. size()方法应始终返回int,泛型类型无关紧要。
  6. 如果不遵守Java语法标准,则会让其他人难以解释您的代码。
  7. 以下代码是您完成目标的正确方法。

    public class NodeStack<T> {
        private Node<T> topOfStack = null;
    
        private static class Node<I> {
            I item;
            Node<I> next;
        }
    
        public void push(T item) {
            Node<T> oldTopOfStack = topOfStack;
            topOfStack = new Node<T>();
            topOfStack.item = item;
            topOfStack.next = oldTopOfStack;
        }
    
        public T pop() {
            T item = topOfStack.item;
            topOfStack = topOfStack.next;
            return item;
        }
    
        public boolean isEmpty() {
            return topOfStack == null;
        }
    
        public int size() {
            int i = 0;
            Node<T> iterate = topOfStack;
            while (iterate != null) {
                iterate = iterate.next;
                i++;
            }
            return i;
        }
    
        public static void main(String[] args) {
            NodeStack<Integer> stackOfIntegers = new NodeStack<Integer>();
            stackOfIntegers.push(1);
            stackOfIntegers.push(2);
            stackOfIntegers.push(3);
            System.out.println(stackOfIntegers.size());
        }
    }