Такой список способен содержать неизвестное заранее количество аргументов неизвестного типа. Так как абсолютно все классы унаследованы от общего корневого класса Object, можно создать метод, принимающий в качестве аргумента массив Object, и вызывать его следующим образом:
//. initialization/VarArgs.java
// Использование синтаксиса массивов
// для получения переменного списка параметров.
class А { int i; }
public class VarArgs {
static void printArray(Object[] args) { for(Object obj • args)
System.out print(obj + " "); System out printlnO,
}
public static void main(String[] args) { printArray(new Object[]{
new Integer(47), new Float(3 14), new Double(ll.ll)
}).
printArray(new 0bject[]{"pa3", "два", "три" }); pri ntArray (new Object[]{new AO, new AO, new AO});
}
} /* Output: (Sample) 47 3.14 11.11 раз два три
А@1а46еЗО А@3е25а5 A@19821f *///:-
Видно, что метод print() принимает массив объектов типа Object, перебирает его элементы и выводит их. Классы из стандартной библиотеки Java при печати выводят осмысленную информацию, однако объекты классов в данном примере выводят имя класса, затем символ @ и несколько шестнадцатеричных цифр. Таким образом, по умолчанию класс выводит имя и адрес объекта (если только вы не переопределите в классе метод toString() — см. далее).
До выхода Java SE5 переменные списки аргументов реализовывались именно так. В Java SE5 эта долгожданная возможность наконец-то была добавлена в язык — теперь для определения переменного списка аргументов может использоваться многоточие, как видно в определении метода printArray:
//: initialization/NewVarArgs java // Создание списков аргументов переменной длины // с использованием синтаксиса массивов.
public class NewVarArgs {
static void printArray(Object... args) { for(Object obj • args)
System out.print(obj + " "); System.out.printlnO;
}
public static void main(String[] args) {
// Можно передать отдельные элементы printArray(new Integer(47), new Float(3 14), new Doubledl. 11));
printArray(47. 3 14F, 11.11): printArray("раз", "два", "три"): printArray(new АО. new АО, new АО): // Или массив.
printArray((Object[])new Integer[]{ 1, 2, 3, 4 }); printArray(), // Пустой список тоже возможен
}
} /* Output- (lb% match) 47 3 14 11.11 47 3 14 11.11 раз два три
A@lbab50a А@сЗс749 A@150bd4d 12 3 4 *///•-
Резюме
Такой сложный механизм инициализации, как конструктор, показывает, насколько важное внимание в языке уделяется инициализации. Когда Бьерн Страуструп разрабатывал С++, в первую очередь он обратил внимание на то, что низкая продуктивность С связана с плохо продуманной инициализацией, которой была обусловлена значительная доля ошибок. Аналогичные проблемы возникают и при некорректной финализации. Так как конструкторы позволяют
В языке С++ уничтожение объектов играет очень важную роль, потому что объекты, созданные оператором new, должны быть соответствующим образом разрушены. В Java память автоматически освобождается сборщиком мусора, и аналоги деструкторов обычно не нужны. В таких случаях сборщик мусора Java значительно упрощает процесс программирования и к тому же добавляет так необходимую безопасность при освобождении ресурсов. Некоторые сборщики мусора могут проводить завершающие действия даже с такими ресурсами, как графические и файловые дескрипторы. Однако сборщики мусора добавляют издержки во время выполнения программы, которые пока трудно реально оценить из-за сложившейся исторически медлительности интерпретаторов Java. И хотя в последнее время язык Java намного улучшил свою производительность, проблема его «задумчивости» все-таки наложила свой отпечаток на возможность решения языком некоторого класса задач.
Так как для всех объектов гарантированно используются конструкторы, на последние возлагаются дополнительные обязанности, не описанные в этой главе. В частности, гарантия конструирования действует и при создании новых классов с использованием
Управление доступом
Это особенно важно для библиотек. Пользователь