pengguang001
pengguang001

Reputation: 4205

static inner class - weird

My code:

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);
        }
    }
}

It will complain an error: "MyTest.java:41: non-static variable this cannot be referenced from a static context"

Remove this line will pass compile. However, we need many String objects in the 'static main' method. What's the difference between String and StringSorter?

If I change StringSorter to be static inner class, it will be compiled OK. How does static inner class fix the compile error?

Upvotes: 1

Views: 1100

Answers (3)

Agemen
Agemen

Reputation: 1535

This tutorial explains quite well how to deal with inner classes. In your code, you're trying to use MyTest.StringSorter from your main method. MyTest.main is static, so it can't access the non-static fields, methods, inner classes that are defined in its outer calss.

When making StringSorter static, this inner class can be called from the static methods of the outer class.

When you call your original code, you're not working with an instance of MyTest. You're using one of its static method. it is said in the tutorial that :

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

Hope it's clearer now ;-)

Upvotes: 0

Alba Mendez
Alba Mendez

Reputation: 4605

As dcn has said, you have to add the static keyword to the StringComparator (see below):

public static class StringSorter implements Comparator<String>

Inner classes are usually static, because they normally are utility classes (the same in your case; StringComparator helps you to compare strings based on their lenght).

Upvotes: 0

dcn
dcn

Reputation: 4469

StringSorter is an inner class and is always 'bound' to an instance of the outer class MyTest (it can access its members, call its methods etc...) . Since you try to instantiate it from a static context (the static main method) it fails. Instead you can make the inner class static (like static public class StringSorter) to make it work.

Alternatively you can move StringSorter outside of MyTest in which case they are seperate classes. (If you want to still keep both classes within the same file, you have to remove the public modifier, since only a single public class - with the name of the file - is allowed per source file).

Another alternative would be to move your 'test code' from the main method into some member method of MyTest (therefore non-static context) and call this method...

Upvotes: 2

Related Questions