我的代码:
public class MyTest {
public class StringSorter implements Comparator<String>
{
public StringSorter() {}
public int compare(String s1, String s2)
{
int l1 = s1.length();
int l2 = s2.length();
return l1-l2;
}
}
public static void main(String[] args) {
System.out.println("Hello, world!");
StringSorter sorter = new StringSorter();
Set<String> sets = new TreeSet<String>(sorter);
sets.add(new String("he"));
sets.add(new String("hel"));
sets.add(new String("he"));
sets.add(new String("hello"));
for (String s: sets)
{
System.out.println(s);
}
}
}
会抱怨错误: “MyTest.java:41:非静态变量,无法从静态上下文中引用”
删除此行将通过编译。但是,我们在'static main'方法中需要很多String对象。 String和StringSorter有什么区别?
如果我将StringSorter更改为静态内部类,则它将被编译为OK。静态内部类如何修复编译错误?
答案 0 :(得分:2)
StringSorter
是一个内部类,并且始终“绑定”到外部类MyTest
的实例(它可以访问其成员,调用其方法等...)。由于您尝试从静态上下文(静态主方法)实例化它,因此失败。相反,你可以使内部类静态(如static public class StringSorter
)使其工作。
或者,您可以将StringSorter
移到MyTest
之外,在这种情况下,它们是单独的类。 (如果您仍希望将两个类保留在同一个文件中,则必须删除public
修饰符,因为每个源文件只允许一个公共类 - 具有文件名 - 。
另一种方法是将'测试代码'从main方法移动到MyTest
的某个成员方法(因此是非静态上下文)并调用此方法...
答案 1 :(得分:0)
正如dcn所说,你必须将static
关键字添加到StringComparator
(见下文):
public static class StringSorter implements Comparator<String>
内部类通常是静态,因为它们通常是实用程序类(在您的情况下相同; StringComparator
可帮助您根据字符串长度比较字符串)。
答案 2 :(得分:0)
This tutorial很好地解释了如何处理内部类。在您的代码中,您尝试使用main方法中的MyTest.StringSorter
。 MyTest.main
是静态的,因此它无法访问在其外部calss中定义的非静态字段,方法,内部类。
当使StringSorter
为静态时,可以从外部类的静态方法调用此内部类。
当您拨打原始代码时,您没有使用MyTest
的实例。您正在使用其静态方法之一。在教程中说:
可以存在InnerClass的实例 仅在OuterClass的一个实例中 并可直接访问这些方法 及其封闭实例的字段。
希望现在更清楚了; - )