静态内部阶级 - 怪异

时间:2011-05-05 10:04:03

标签: java static inner-classes

我的代码:

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。静态内部类如何修复编译错误?

3 个答案:

答案 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.StringSorterMyTest.main是静态的,因此它无法访问在其外部calss中定义的非静态字段,方法,内部类。

当使StringSorter为静态时,可以从外部类的静态方法调用此内部类。

当您拨打原始代码时,您没有使用MyTest的实例。您正在使用其静态方法之一。在教程中说:

  

可以存在InnerClass的实例   仅在OuterClass的一个实例中   并可直接访问这些方法   及其封闭实例的字段。

希望现在更清楚了; - )