繁体   English   中英

具有接口的静态上下文错误中引用的非静态变量

[英]Non-static variable referenced in static context error with interface

我对Java(尤其是接口)相当新,我设置了这个简单的比较接口,并且希望为它创建一个整数实现。 编译时,编译器返回一个错误,指出我无法在静态上下文中引用此非静态变量。 我理解这个错误......但我不确定为什么会发生这种情况。

根据我见过的例子,初始化看起来是正确的。 也许我只需要另一组眼睛来查看这段代码,看看我错过了什么。

我感谢任何帮助。

public class Test
{
    public static void main(String[] args)
    {
        Icmp test = new Icmp();
    }

    public interface Cmp
    {
        public int cmp(Object x, Object y);
    }

    class Icmp implements Cmp
    {
        public int cmp(Object o1, Object o2)
        {
            int i1 = ((Integer) o1).intValue();
            int i2 = ((Integer) o2).intValue();

            if(i1<i2)
                return -1;
            else if(i1==i2)
                return 0;
            else
                return 1;
        }
    }
}

违规行:

    Icmp cmp = new Icmp();

错误:

LabFour.java:20: non-static variable this cannot be referenced from a static context
        Icmp cmp = new Icmp();
                   ^

好吧,现在好多了。 关键是,接口和类都不是静态的 - 它们只能使用Test实例创建,请尝试

Icmp test = (new Test()).new Icmp()

或者,您可以考虑使内部类和接口静态:

public class Test {
    public static void main(String[] args) {
        Icmp test = new Icmp();
    }

    public static interface Cmp {
        public int cmp(Object x, Object y);
    }

    static class Icmp implements Cmp {
        public int cmp(Object o1, Object o2) {
            int i1 = ((Integer) o1).intValue();
            int i2 = ((Integer) o2).intValue();

            if (i1 < i2)
                return -1;
            else if (i1 == i2)
                return 0;
            else
                return 1;
        }
    }
}

另一种选择是摆脱内部类/接口:

interface Cmp {
    public int cmp(Object x, Object y);
}

class Icmp implements Cmp {
    public int cmp(Object o1, Object o2) {
        int i1 = ((Integer) o1).intValue();
        int i2 = ((Integer) o2).intValue();

        if (i1 < i2)
            return -1;
        else if (i1 == i2)
            return 0;
        else
            return 1;
    }
}

public class Test {
    public static void main(String[] args) {
        Icmp test = new Icmp();
    }
}

如您所见,所有解决方案都相似 - 这就是为什么实际代码对于获得合理答案至关重要。

跟进注释:内部类(字面意思是另一个类中的类)意味着该类是封闭对象的一部分。 或者,如果它是静态的 - 封闭类的一部分。 非静态内部类的重要之处在于它们可以访问封闭对象的成员(字段,方法,包括私有内容); 因此棘手的语法。

为了使内部类对象能够做到这一点,它存储对封闭对象的隐式引用。

使用接口,正如@Voo正确地说,你永远不会访问任何东西,并且永远不会有任何引用 - 内部接口始终是静态的。

如需进一步阅读,请参阅Kathy Sierra的书籍。 或者JLS如果您更喜欢硬核规格。

这里有三个独立的部分:Interface Cmp ,Implementation IcmpLabFour.java实现的用户。

这些文件是什么? 您应该有三个文件: Cmp.javaIcmp.javaLabFour.java如果在Icmp.java有一个测试main()方法,则只能有两个文件

Icmp类应该是公开的。

您需要更多地显示LabFour.java以显示您的“违规行”所处的上下文。


编辑。

在您的新Test示例中,错误正在发生, 因为它全部在一个文件中定义。

Icomp是一个内部类的类的Test和内类需要包含类的实例来工作。

您需要创建Test类的封闭实例。 将您的主要内容更改为:

public static void main(String[] args)
{
    Test t = new Test(); // enclosing instance of Test
    Icmp test = t.new Icmp(); // create an Icmp in the context of 't'
}

如果我已经提到过Test,Cmp和Icmp在三个单独的文件中定义,这也可以工作。

因为Icmp实际上并没有使用封闭的Test实例,所以最好让它成为一个静态的Test类,假设你真的想把它保存在Test

static class Icmp implements Cmp { ... }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM