Нестатическая переменная, на которую ссылается ошибка статического контекста с интерфейсом - PullRequest
0 голосов
/ 21 октября 2011

Я довольно новичок в 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();
                   ^

Ответы [ 3 ]

2 голосов
/ 21 октября 2011

Ну, теперь лучше. Дело в том, что ни интерфейс, ни класс не являются статическими - их можно создать только с использованием экземпляра 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, вы никогда не получаете доступ к чему-либо и никогда не имеете ссылок - внутренние интерфейсы всегда статичны.

Для дальнейшего чтения возьмите книги Кэти Сьерра. Или JLS, если вы предпочитаете хардкорные спецификации.

0 голосов
/ 21 октября 2011

Поскольку Icmp на самом деле не использует включающий экземпляр Test, было бы лучше либо сделать его статическим классом Test, предполагая, что вы действительно хотите сохранить его внутри Test.

static class Icmp implements Cmp { ... }
0 голосов
/ 21 октября 2011

Здесь есть три отдельных элемента: интерфейс Cmp, реализация Icmp и пользователь реализации LabFour.java.

В каких файлах они находятся? У вас должно быть три файла: Cmp.java, Icmp.java и LabFour.java Вы можете иметь только два файла, если у вас есть метод теста main() в Icmp.java

Класс Icmp, вероятно, должен быть общедоступным.

Вам нужно показать больше того, что в LabFour.java, чтобы показать, в каком контексте находится ваша «оскорбительная линия».


Edit.

В вашем новом примере 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, как я уже упоминал, были определены в трех отдельных файлах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...