Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
35
Добавлен:
27.03.2015
Размер:
118.27 Кб
Скачать

Создание и инициализация объектов (2)

В момент создания объекта:

-выделяется память для хранения значений полей экземпляра класса (указатели на статические поля, на методы и конструкторы хранятся в самом классе);

-вызывается конструктор, соответствующий указанному в операторе new перечню аргументов и получающий кроме них переменную this (указатель на память объекта) и переменную super (указатель на родительский класс);

-в каждый конструктор компилятором неявно встраиваются коды инициализаторов всех полей экземпляра класса, но только в том случае, если код конструктора не начинается с вызова другого конструктора (пример на следующем слайде);

-инициализация полей выполняется в том порядке, в котором поля появляются в определении класса – это значит, что выражение инициализации некоторого поля может включать значения полей, проинициализированных ранее по тексту;

-после инициализации всех полей выполняется тело конструктора.

Создание и инициализация объектов (3) Пример

class myClass {

 

 

static String version;

// это поле класса

int stepIndicator[ ] = new int[ 100 ];

// а это поле экземпляра

myClass() { // в этот конструктор инициализаторы не встраиваются this( 1 );

}

{ for( int i =0; i < 100; i++) // это блок инициализатора поля экземпляра stepIndicator[ i ] = i % 2 == 0? 2 * i + 3 : i - 1; }

myClass( int subVersion ) { // в этом конструкторе вначале будет

//вызван конструктор суперкласса: super(); ,

//затем выполнен блок инициализатора,

version += "." + subVersion; // а в конце – этот оператор

}

 

 

static {

 

// это блок инициализатора поля класса.

version = "1.0.21";

// Он выполняется в тот момент, когда этот

}

 

// класс впервые загружается в данном приложении

// другие поля, методы, конструкторы и инициализаторы

}

Уничтожение объектов

В связи с тем, что память объектов в Java не освобождается явно (невозможно управлять моментом времени, когда сборщик мусора определит ненужность данного экземпляра), классы не имеют деструкторов.

Тем не менее, существует возможность определить в классе специальный метод с фиксированным именем finalize (не получающим аргументов и не возвращающий результат), который может быть будет вызван (но не обязательно будет!!!) в отдельном потоке (Finalyzer) после того, как сборщик мусора определит, что на объект больше нет актуальных ссылок.

Метод finalize должен явно вызывать финализатор родительского класса: super.finalize();

Использовать финализаторы следует крайне осторожно и только в том случае, если при работе экземпляра класса вызывались «нативные» функции, которые захватывали ресурсы (память, файлы, …), которые требуется освободить.

Даже в этом случае лучше освобождать ресурсы путем написания метода, вызываемого явно перед тем, как экземпляр класса становится мусором.

Пример объявления классов и работы с объектами (1)

package oopsamples;

// имя пакета

class ListItem<T> {

// элемент списка элементов типа T

 

// ListItem<T> - параметризованный тип

private T value;

// значение элемента

protected ListItem next = null; // ссылка на следующий элемент в списке

public ListItem ( ) {

// этот конструктор нужен, чтобы создавать

}

// объекты так: ListItem myItem = new ListItem();

ListItem ( T value ) {

// другой конструктор

this.value = value;

//разрешение коллизии имен

}

 

public T getValue( ) {

// типичная пара методов get/set

return value;

 

}

public void setValue( T value ) { this.value = value;

}

}

Пример объявления классов и работы с объектами (2)

class MyListEmpty extends Exception {

// это класс исключений при

private String message;

// работе с ListItem

MyListEmpty( String message ){

// конструктор, принимающий

this.message = message;

// сообщение об исключении

}

 

@Override // это аннотация – метаданные, не влияющие на

//поведение программы, но используемые компилятором

//в этом случае она явно указывает компилятору на

//то, что замещается метод родительского класса

public String getMessage( ) {

// один из методов

return message;

// объекта «исключение»

}

 

}

Пример объявления классов и работы с объектами (3)

class LifoList<T> extends ListItem<T> {

// список типа «стек»

private int count = 0;

// количество элементов в стеке

public LifoList( ) {

 

}

 

public void put( T element ) {

// занесение экземпляра типа T

ListItem<T> newItem = new ListItem<T>( element ); // в стек

newItem.next = next;

 

next = newItem;

 

count += 1;

 

}

 

public T get( ) throws MyListEmpty {

// снятие элемента с верхушки стека

if( next == null )

// исключение, если стек пуст

throw new MyListEmpty( "Stack is empty" );

T retElement = ( T )( next.getValue( ) );

// объект выбирается из элемента

next = next.next;

// следующий элемент становится верхним

count -= 1;

 

return retElement;

// экземпляр типа T возвращается

}

 

public int size( ) {

// возвращается текущее

return count;

// количество элементов стека

}

 

}

Пример объявления классов и работы с объектами (4)

public class Main {

public static void main( String[ ] args ) {

LifoList<String> myStack = new LifoList<String>( ); // создание стека

myStack.push( "First string" );

// занесение строки в стек

myStack.push( "Second string" );

// занесение второй строки

try {

 

 

System.out.println( myStack.get( ) );

// выборка последнего

System.out.println( myStack.get( ) );

// выборка предыдущего

System.out.println( myStack.get( ) );

// здесь будет исключение

} catch( Exception e ) {

}

System.out.println( e.getMessage( ) );

 

Second string

 

}

 

First string

}

 

Stack is empty

 

 

 

Пример объявления классов и работы с объектами (5)

class FifoList<T> extends ListItem<T> {

//другой список – очередь

private int count = 0;

 

private ListItem<T> lastItem = null;

//в отличие от стека нужна

public FifoList() {

//дополнительная переменная

 

}

 

public void put( T element ) {

//помещение объекта в очередь

ListItem<T> newItem = new ListItem<T>( element ); //создание элемента

if( lastItem != null )

//если очередь не пуста

lastItem.next = newItem;

//то ссылка на новый пишется

 

//в элемент, бывший последним

lastItem = newItem;

//новый становится последним

if( next == null )

//если очередь пуста

next = newItem;

//то новый становится и первым

count += 1;

 

}

 

Пример объявления классов и работы с объектами (6)

public T get( ) throws MyListEmpty {

//выборка из очереди

if( next == null )

//исключение, если очередь пуста

throw new MyListEmpty( "Queue is empty" );

T retElement = ( T ) ( next.getValue( ) ); //объект выбирается из элемента

next = next.next;

//элемент, следующий за первым

 

//становится первым

if( next == null )

//если первого не стало

lastItem = null;

//то не стало и последнего

count -= 1;

 

return retElement;

//возврат объекта

}

 

public int size( ) {

// возвращается текущее

return count;

// количество элементов

}

 

}

// выборка первого // выборка второго
// попытка выборки из
1
2
Queue is empty

Пример объявления классов и работы с объектами (7)

public class Main {

public static void main( String[ ] args ) {

FifoList<Integer> myQueue = new FifoList<Integer>( ); // новая очередь

myQueue.put( new Integer( 1 ) );

// занесение первого

myQueue.put( 2 );

// здесь работает «autoboxing»

try {

 

System.out.println( myQueue.get( ) );

System.out.println( myQueue.get( ) );

System.out.println( myQueue.get( ) );

//пустой очереди

} catch( Exception e ) {

System.out.println( e.getMessage( ) );

}

}

}

Соседние файлы в папке Презентации по Java