АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Java.lang.String Java SE 6

Читайте также:
  1. Biglnteger Классы
  2. Создание POJO-классов

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();//неопределенность!

}

}

В результате будет выведено:


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.014 сек.)