|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Java.lang.String Java SE 6
Java.lang.Integer 71 В рассмотренном примере были созданы объекты типа Optional: ob1 на основе типа Integer и ob2 на основе типа String при помощи различных конструкторов. При компиляции вся информация о generic-типах стирается и заменяется для членов класса и методов заданными типами или типом Object, если параметр не задан, как для объекта ob3. Такая реализация необходима для обеспечения совместимости с кодом, созданным в предыдущих версиях языка. Объявление generic-типа в виде <T>, несмотря на возможность использовать любой тип в качестве параметра, ограничивает область применения разрабатываемого класса. Переменные такого типа могут вызывать только методы класса Object. Доступ к другим методам ограничивает компилятор, предупреждая возможные варианты возникновения ошибок. Чтобы расширить возможности параметризованных членов класса, можно ввести ограничения на используемые типы при помощи следующего объявления класса: public class OptionalExt <T extends Tип> { private T value; } Такая запись говорит о том, что в качестве типа Т разрешено применять только классы, являющиеся наследниками (суперклассами) класса Tип, и соответственно появляется возможность вызова методов ограничивающих (bound) типов. Часто возникает необходимость в метод параметризованного класса одного допустимого типа передать объект этого же класса, но параметризованного другим типом. В этом случае при определении метода следует применить метасимвол?. Метасимвол также может использоваться с ограничением extends для передаваемого типа. /*пример # 11: использование метасимвола в параметризованном классе: Mark.java, Runner.java */ package chapt03;
public class Mark<T extends Number> { public T mark;
public Mark(T value) { mark = value; } public T getMark() { return mark; } public int roundMark() { return Math. round (mark.floatValue()); } /* вместо */ // public boolean sameAny(Mark<T> ob) { public boolean sameAny(Mark<?> ob) { return roundMark() == ob.roundMark(); } public boolean same(Mark<T> ob) { return getMark() == ob.getMark(); } } package chapt03;
public class Runner { public static void main(String[] args) { // Mark<String> ms = new Mark<String>(“7”); //ошибка компиляции Mark<Double> md = new Mark<Double>(71.4D); //71.5d System. out. println(md.sameAny(md)); Mark<Integer> mi = new Mark<Integer>(71); System. out. println(md.sameAny(mi)); // md.same(mi); //ошибка компиляции System. out. println(md.roundMark()); } } В результате будет выведено: True True Метод sameAny(Mark<?> ob) может принимать объекты типа Mark, инициализированные любым из допустимых для этого класса типов, в то время как метод с параметром Mark<T> мог бы принимать объекты с инициализацией того же типа, что и вызывающий метод объект. Для generic-типов существует целый ряд ограничений. Например, невозможно выполнить явный вызов конструктора generic-типа: class Optional <T> { T value = new T(); } так как компилятор не знает, какой конструктор может быть вызван и какой объем памяти должен быть выделен при создании объекта. По аналогичным причинам generic-поля не могут быть статическими, статические методы не могут иметь generic-параметры или обращаться к generic-полям, например: /*пример # 12: неправильное объявление полей параметризованного класса: Failed.java */ package chapt03; class Failed <T1, T2> { static T1 value; T2 id;
static T1 getValue() { return value; } static void use() { System. out. print(id); } } Параметризованные методы Параметризованный (generic) метод определяет базовый набор операций, которые будут применяться к разным типам данных, получаемых методом в качестве параметра, и может быть записан, например, в виде: <T extends Тип> returnType methodName(T arg) {} <T> returnType methodName(T arg) {} Описание типа должно находиться перед возвращаемым типом. Запись первого вида означает, что в метод можно передавать объекты, типы которых являются подклассами класса, указанного после extends. Второй способ объявления метода никаких ограничений на передаваемый тип не ставит. Generic-методы могут находиться как в параметризованных классах, так и в обычных. Параметр метода может не иметь никакого отношения к параметру своего класса. Метасимволы применимы и к generic-методам. /* пример # 13: параметризованный метод: GenericMethod.java */ public class GenericMethod { public static <T extends Number> byte asByte(T num) { long n = num.longValue(); if (n >= -128 && n <= 127) return (byte)n; else return 0; } public static void main(String [] args) { System. out. println(asByte (7)); System. out. println(asByte (new Float("7.f"))); // System.out.println(asByte(new Character('7'))); // ошибка компиляции } } Объекты типа Integer (int будет в него упакован) и Float являются подклассами абстрактного класса Number, поэтому компиляция проходит без затруднений. Класс Character не обладает вышеуказанным свойством, и его объект не может передаваться в метод asByte(T num). Методы с переменным числом параметров Возможность передачи в метод нефиксированного числа параметров позволяет отказаться от предварительного создания массива объектов для его последующей передачи в метод. /* пример # 14: определение количества параметров метода: DemoVarargs.java */ package chapt03;
public class DemoVarargs { public static int getArgCount(Integer... args) { if (args.length == 0) System. out. print("No arg="); for (int i: args) System. out. print("arg:" + i + " "); return args.length; } public static void main(String args[]) { System. out. println("N=" + getArgCount (7, 71, 555)); Integer[] i = { 1, 2, 3, 4, 5, 6, 7 }; System. out. println("N=" + getArgCount (i)); System. out. println(getArgCount ()); } } В результате выполнения этой программы будет выведено: arg:7 arg:71 arg:555 N=3 arg:1 arg:2 arg:3 arg:4 arg:5 arg:6 arg:7 N=7 No arg=0 В примере приведен простейший метод с переменным числом параметров. Метод getArgCount() выводит все переданные ему аргументы и возвращает их количество. При передаче параметров в метод из них автоматически создается массив. Второй вызов метода в примере позволяет передать в метод массив. Метод может быть вызван и без аргументов. Чтобы передать несколько массивов в метод по ссылке, следует использовать следующее объявление: void methodName(Тип[]... args){} Методы с переменным числом аргументов могут быть перегружены: void methodName(Integer...args) {} void methodName(int x1, int x2) {} void methodName(String...args) {} В следующем примере приведены три перегруженных метода и несколько вариантов их вызова. Отличительной чертой является возможность метода с аргументом Object... args принимать не только объекты, но и массивы: /* пример # 15: передача массивов: DemoOverload.java */ package chapt03;
public class DemoOverload { public static void printArgCount(Object... args) { //1 System. out. println("Object args: " + args.length); } public static void printArgCount(Integer[]...args){ //2 System. out. println("Integer[] args: " + args.length); } public static void printArgCount(int... args) { //3 System. out. print("int args: " + +args.length); } public static void main(String[] args) { Integer[] i = { 1, 2, 3, 4, 5 };
printArgCount (7, "No", true, null); printArgCount (i, i, i); printArgCount (i, 4, 71); printArgCount (i); //будет вызван метод 1 printArgCount (5, 7); // printArgCount();//неопределенность! } } В результате будет выведено: Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.014 сек.) |