Доступ к переменным класса внутренних объектов

В моем основном классе есть внутренний класс Shape, который расширяет JButton. Этот внутренний класс имеет приватную переменную char, которая называется CUBE.

Я написал для него геттеры и сеттеры. Я заметил, что в основном методе вместо использования:

(instance of Shape).getCUBE(); 

Я могу получить к нему доступ, используя:

(instance of Shape).CUBE

Это происходит потому, что CUBE в конечном счете находится в том же классе, что и main?

Необходимо ли в соответствии с соглашениями о программировании Java, чтобы я писал геттеры и сеттеры для такого внутреннего класса?


person Zenos    schedule 13.05.2012    source источник
comment
Кстати, это не должно быть заглавными буквами.   -  person SLaks    schedule 13.05.2012


Ответы (3)


Это происходит потому, что CUBE в конечном счете находится в том же классе, что и main?

Нет, это работает, потому что так написано в спецификации языка. В конечном итоге он станет отдельным классом для JVM, но будут созданы дополнительные методы уровня пакета, чтобы внешний класс выглядел как нарушающий обычные правила.

Соответствующий раздел спецификации языка находится в 6.6.1:

В противном случае, если член или конструктор объявлен закрытым, доступ разрешается тогда и только тогда, когда он происходит в теле класса верхнего уровня (§7.6), который содержит объявление члена или конструктора.

(Выделение мое.)

Таким образом, даже вложенные классы peer имеют доступ к закрытым членам. Образец кода:

public class Test {

    public static void main(String[] args) {
        First first = new First(10);
        Second second = new Second(first);
        System.out.println(second.getValueFromFirst());
    }

    private static class First {        
        private final int value;

        private First(int value) {
            this.value = value;
        }
    }

    private static class Second {
        private final First first;

        private Second(First first) {
            this.first = first;
        }

        private int getValueFromFirst() {
            return first.value;
        }
    }
}

Если вы посмотрите на сгенерированные классы (с javap -c Test$First и javap -c Test$Second, вы увидите синтетические методы, сгенерированные компилятором.

person Jon Skeet    schedule 13.05.2012
comment
большое спасибо! будет ли по-прежнему необходимо по соглашению Java писать геттеры и сеттеры? также было бы предпочтительнее использовать их вместо экземпляра object.variable? - person Zenos; 13.05.2012
comment
Я не уверен, правда. Я видел много кода в обоих направлениях. Я обычно делаю вложенный класс приватным (если только это не что-то вроде построителя) для ясности. - person Jon Skeet; 13.05.2012

Это класс для имитации вашего описания:

import javax.swing.JButton;

class Main
{
   public class Shape extends JButton
   {
      private char CUBE = 'I';

      public char getCUBE()
      {
             return CUBE;
      }
      public void setCUBE(char CUBE){this.CUBE = CUBE;}
   }

   public static void main(String[] args) 
   {
      Shape sp = new Main().new Shape();
      System.out.println(sp.CUBE);
      System.out.println(sp.getCUBE());
   }
}

public class TestMain
{
    public static void main(String[] args) 
    {
     Main.Shape sp = new Main().new Shape();
     //System.out.println(sp.CUBE);
     System.out.println(sp.getCUBE());
    }
}

Если вы удалите комментарий, он не будет скомпилирован. Поэтому, если вы хотите получить доступ к CUBE вне Main, вам все равно понадобятся геттер и сеттер.

person dragon66    schedule 13.05.2012

Это работает, потому что вы забыли добавить ключевое слово private.

person SLaks    schedule 13.05.2012
comment
Нет, он доступен, даже если он частный. - person Jon Skeet; 13.05.2012