Читайте также:
|
|
Java не поддерживает концепцию C++ связанную с деструктором, специальным методом, который автоматически вызывается при уничтожении объекта. Причина этого в том, что в Java нужно просто забыть об объекте, позволяя тем самым освободить сборщику мусора память, если это необходимо.
Зачастую этот подход отлично работает, но иногда ваш класс может осуществлять некоторые действия во время его цикла жизни и требуется его очистить грамотно. Как уже упоминалось в главе 4, Вы не можете знать когда будет вызван сборщик мусора, и будет ли он вообще вызван. Так что, если Вы хотите очистить нечто в вашем классе, то Вам необходимо просто написать специальный метод выполняющий эту работу, и убедиться, что другой (возможный) программист знает, что он должен взывать этот метод. Эта проблема описана в главе 10 ("Обработка ошибок с помощью исключений"), Вы должны обработать исключение поместив некий очищающий код в блок finally.
Давайте рассмотрим пример вспомогательной компьютерной системы дизайна, которая рисует картинку на экране:
//: c06:CADSystem.java// Обеспечение правильной очистки.import java.util.*; class Shape { Shape(int i) { System.out.println("Shape constructor"); } void cleanup() { System.out.println("Shape cleanup"); }} class Circle extends Shape { Circle(int i) { super(i); System.out.println("Drawing a Circle"); } void cleanup() { System.out.println("Erasing a Circle"); super.cleanup(); }} class Triangle extends Shape { Triangle(int i) { super(i); System.out.println("Drawing a Triangle"); } void cleanup() { System.out.println("Erasing a Triangle"); super.cleanup(); }} class Line extends Shape { private int start, end; Line(int start, int end) { super(start); this.start = start; this.end = end; System.out.println("Drawing a Line: " + start + ", " + end); } void cleanup() { System.out.println("Erasing a Line: " + start + ", " + end); super.cleanup(); }} public class CADSystem extends Shape { private Circle c; private Triangle t; private Line[] lines = new Line[10]; CADSystem(int i) { super(i + 1); for(int j = 0; j < 10; j++) lines[j] = new Line(j, j*j); c = new Circle(1); t = new Triangle(1); System.out.println("Combined constructor"); } void cleanup() { System.out.println("CADSystem.cleanup()"); // Порядок очистки // обратен порядку инициализации t.cleanup(); c.cleanup(); for(int i = lines.length - 1; i >= 0; i--) lines[i].cleanup(); super.cleanup(); } public static void main(String[] args) { CADSystem x = new CADSystem(47); try { // Код и исключения обрабатываются... } finally { x.cleanup(); } }} ///:~Все в этой системе является разновидностями шейпа (Shape) (который в свою очередь является разновидностью объекта(Object) в силу того, что он косвенным образом наследует корневой класс). Каждый класс переопределяет метод шейпа cleanup() в дополнении к этому еще и вызывает метод базового класса через использование super. Специфичные классы Shape, такие, как Circle, Triangle и Line все имеют конструкторы, которые рисуют, хотя любой метод, вызванный во время работы, должен быть доступным для чего либо нуждающегося в очистке. Каждый класс имеет свой собственный метод cleanup() для восстановления не использующих память вещей существовавших до создания объекта.
В методе main(), Вы можете видеть два ключевых слова, которые для Вас новы, и не будут официально представлены до главы 10: try и finally. Ключевое слово try сигнализирует о начале блока (отделенного фигурными скобками), который является охраняемой областью, что означает, что он предоставляет специальную обработку при возникновении исключений. Одной из специальных обработок является порция кода заключенная в блок finally следующий за охраняемой областью и который всегда выполняется, вне зависимости от завершения блока try. (С обработкой исключений имеется возможность покинуть блок try бесчисленным количеством способов.) Здесь, finally означает:"Всегда вызывать cleanup() для x, без разницы, что случилось". Эти ключевые слова будут основательно разъяснены в главе 10.
Заметьте, что в Вашем методе очистки Вы должны так же быть внимательны в вызове очередности для базового класса и для вашего класса, в зависимости от отношений с подобъектом. В основном, Вы должны следовать тем же путем, как и в C++ в деструткорах: Сначала осуществляется очистка вашего класса в обратной последовательности создания. (В основном требуется, чтобы элементы базового класса были все еще доступны.) Затем вызвать метод очистки базового класса, как показано в примере.
Вообще может быть множество случаев, в которых очистка это не проблема, Вы просто позволяете сборщику мусора выполнить свою работу. Но, когда Вы должны очистку сделать самостоятельно, следует быть внимательным, усердным и осторожным.
Дата добавления: 2015-09-11; просмотров: 82 | Поможем написать вашу работу | Нарушение авторских прав |