我是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();
^
答案 0 :(得分:2)
嗯,现在好多了。关键是,接口和类都不是静态的 - 它们只能使用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,如果您更喜欢硬核规格。
答案 1 :(得分:0)
此处有三个单独的部分:界面Cmp
,实施Icmp
和实施用户LabFour.java
。
这些文件是什么?您应该有三个文件:Cmp.java
,Icmp.java
和LabFour.java
如果main()
Icmp.java
方法,则只能有两个文件
班级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在三个单独的文件中定义,这也会有效。
答案 2 :(得分:0)
因为Icmp
实际上并没有使用封闭的Test
实例,所以最好让它成为Test
的静态类,假设你真的希望将其保留在Test
内。
static class Icmp implements Cmp { ... }