Static внутренние классы
Если вам не нужно соединение между внутренним классом и объектом внешнего класса, тогда Вы можете сделать этот внутренний класс static. Для того, что бы понять значение static примененного к внутреннему классу, Вы должны вспомнить то, что этот объект обычного внутреннего класса неявным образом ссылается на объект создавшего его окружающего класса. А если Вы объявите его как static, то это уже не будет правдой. Static внутренний класс означает:
Static внутренние классы отличаются от не-static внутренних классов. Поля и методы в не-static внутренних классах могут быть только на внешнем уровне класса, поэтому не-static внутренние классы не могут иметь static данные, static поля или static внутренние классы. Однако static внутренний класс не ограничен таким ограничением:
//: c08:Parcel10.java
// Static внутренний класс.
public class Parcel10 { private static class PContents implements Contents { private int i = 11; public int value() { return i; } } protected static class PDestination implements Destination { private String label; private PDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } // Static внутренний класс может содержать
// другие static элементы:
public static void f() {} static int x = 10; static class AnotherLevel { public static void f() {} static int x = 10; } } public static Destination dest(String s) { return new PDestination(s); } public static Contents cont() { return new PContents(); } public static void main(String[] args) { Contents c = cont(); Destination d = dest("Tanzania"); } } ///:~
В main( ), не требуется объекта Parcel10; вместо этого Вы используете нормальный синтаксис для выбора static элемента, что бы вызвать методы, которые возвращают ссылки на Contents и Destination.
Как Вы видели недавно, в обычном (не static) внутреннем классе, ссылка на объект внешнего класса достигается с помощью специальной ссылки this. Static внутренний класс не имеет этой специальной ссылки, что делает его аналогом static метода.
Обычно Вы не можете поместить какой либо код внутрь interface, но static внутренний класс может быть частью interface. Поскольку этот класс static, то он не нарушит правила для интерфейсов - static внутренний класс, только помещается он внутри поля имени интерфейса:
//: c08:IInterface.java
// Static внутренний класс внутри интерфейса.
interface IInterface { static class Inner { int i, j, k; public Inner() {} void f() {} } } ///:~
Раньше в этой книге, я предлагал помещать main( ) в каждый класс, что бы иметь возможность его тестировать. Препятствием для этого может служить, избыточный компилированный код. Если он сильно досаждает, то Вы можете использовать static внутренний класс для минимизации вашего тестового кода:
//: c08:TestBed.java
// Помещаем тестовый код в static внутренний класс.
class TestBed { TestBed() {} void f() { System.out.println("f()"); } public static class Tester { public static void main(String[] args) { TestBed t = new TestBed(); t.f(); } } } ///:~
При этом создается класс называемый TestBed$Tester (для запуска программы, нужно использовать java TestBed$Tester). Вы можете его использовать для тестирования, но вовсе необязательно включать в поставку вашего продукта.