Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «Ѐилософия Java3Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 85

Автор Π‘Ρ€ΡŽΡ ЭккСль

Map<Person, List<? extends PetΒ» petPeople = new HashMap<Person, Li st<? extends PetΒ»():

(ΠšΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово extends ΠΈ Π²ΠΎΠΏΡ€ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π·Π½Π°ΠΊΠΈ Π±ΡƒΠ΄ΡƒΡ‚ описаны ΠΏΠΎΠ·Π΄Π½Π΅Π΅ Π² этой Π³Π»Π°Π²Π΅.) Казалось Π±Ρ‹, эта конструкция ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½Π°, Π° компилятор ΠΌΠΎΠ³ Π±Ρ‹ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· списков Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠΎ-Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ. Π’ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚, Π½ΠΎ вычислСниС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ‚ΠΈΠΏΠΎΠ² всС ΠΆΠ΅ позволяСт Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄. НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ статичСскими ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ, содСрТащими самыС распространСнныС Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ²:

//: net/mindview/uti1/New.java

// Utilities to simplify generic container creation

// by using type argument inference.

package net mindview util; import java util *.

public class New {

public static <K.V> Map<K,V> map() { return new HashMap<K.V>();

}

public static <T> List<T> list О { return new ArrayList<T>();

}

public static <T> LinkedList<T> 1 ListО { return new Li nkedLi st<T>().

}

public static <T> Set<T> setО { return new HashSet<T>();

}

public static <T> Queue<T> queueO { return new LinkedList<T>();

}

// ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:

public static void main(String[] args) {

Map<String, List<String>> sis = New.mapO; List<String> Is = New listO: Li nkedLi st<String> lis = New.lListO; Set<String> ss = New set(); Queue<String> qs = New.queueO;

}

} ///-

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования прСдставлСны Π² main() β€” вычислСниС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ‚ΠΈΠΏΠΎΠ² устраняСт Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π² ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠΈ списков ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΈΠ΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² holding/MapOfList.java:

II- generics/SimplerPets.java import typeinfo.pets.*; import java util *; import net.mindview.util.*;

public class SimplerPets {

public static void main(String[] args) {

Map<Person, Li st<? extends PetΒ» petPeople = New map(); // ΠžΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ...

}

} ///.-

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ интСрСсный, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, насколько ΠΎΠ½ эффСктивСн Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π§Π΅Π»ΠΎΠ²Π΅ΠΊΡƒ, Ρ‡ΠΈΡ‚Π°ΡŽΡ‰Π΅ΠΌΡƒ ΠΊΠΎΠ΄, придСтся ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΈ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² Π΅Π΅ ΠΊΠΎΠ΄Π΅. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, вмСсто этого стоит ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ исходноС (ΠΏΡƒΡΡ‚ΡŒ ΠΈ ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΠΎΠ΅) ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ β€” ΠΊΠ°ΠΊ Π½ΠΈ ΠΏΠ°Ρ€Π°Π΄ΠΎΠΊΡΠ°Π»ΡŒΠ½ΠΎ, этот Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΏΡ€ΠΎΡ‰Π΅. Π₯отя, Ссли Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Java Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Π½Π΅ΠΊΠΎΠ΅ ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ New.java, ΠΈΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ.

ВычислСниС Ρ‚ΠΈΠΏΠΎΠ² Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½ΠΈ Π² ΠΊΠ°ΠΊΠΈΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ситуациях, ΠΊΡ€ΠΎΠΌΠ΅ присваивания. Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° (скаТСм, New.mapO) Π² Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, компилятор Π½Π΅ пытаСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ вычислСниС Ρ‚ΠΈΠΏΠ°. ВмСсто этого Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° интСрпрСтируСтся Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Ссли Π±Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Π»ΠΎΡΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° Object. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ошибки Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π°:

//: generics/LimitsOfInference.java import typeinfo.pets.*; import java.util.*;

public class LimitsOflnference { static void

f(Map<Person, List<? extends PetΒ» petPeople) {} public static void main(String[] args) {

// f(New.mapO); II He компилируСтся

}

} ///:-

Π―Π²Π½ΠΎΠ΅ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ явно Π·Π°Π΄Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ, хотя Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ этот синтаксис ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ€Π΅Π΄ΠΊΠΎ. Π’ΠΈΠΏ указываСтся Π² ΡƒΠ³Π»ΠΎΠ²Ρ‹Ρ… скобках Π·Π° Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ, нСпосрСдствСнно ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… класса Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ this ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ, Π° ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ статичСских ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ указываСтся имя класса. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, продСмонстрированная Π² LimitsOflnference.java, Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ синтаксиса:

//: generics/ExplicitTypeSpecification.java import typeinfo.pets.*: import java.util.*; i mport net.mi ndvi ew.uti1.*:

public class ExplicitTypeSpecification {

static void f(Map<Person, List<Pet>> petPeople) {} public static void main(String[] args) { f(New. <Person, Li st<PetΒ»map()):

}

} ///:-

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΏΡ€ΠΈ этом Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ прСимущСства ΠΎΡ‚ использования класса New для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ объСма ΠΊΠΎΠ΄Π°, Π½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ синтаксис Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ присваивания.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ списки Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ ΡΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ списками Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²:

II: generics/GenericVarargs.java import java.util.*;

public class GenericVarargs {

public static <T> List<T> makeList(T... args) { List<T> result = new ArrayList<T>(); for(T item : args)

result.add(item);-return result;

public static void main(String[] args) { List<String> Is = makeListCA"); System out.println(ls); Is - makeListCA", "Π’". "Π‘"); System.out.println(ls);

Is = makeListC"ABCDEFFHIJKLMNOPQRSTUVWXYZ".split("")); System.out.printi n( Is);

}

} /* Output: [A]

[А, Π’. C]

[, А, Π’. C. D, E. F, F, H, I, J. K. L, M, N, 0. P. Q, R. S. T. U. V. W. X, Y, Z] *///β€’-

ΠœΠ΅Ρ‚ΠΎΠ΄ makeList() прСдоставляСт Ρ‚Ρƒ ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ java. util.Arrays.asList() ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

ИспользованиС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² с Generator

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Ρ…ΠΎΡ€ΠΎΡˆΠΎ подходят для заполнСния Collection, ΠΈ для выполнСния этой ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄:

//: generics/Genetcitors.java // ΠžΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ заполнСния ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ import generics.coffee.*; import java.util.*; import net.mindview.util.*;

public class Generators {

public static <T> Collection<T>

fill(Collection<T> coll. Generator<T> gen, int n) { for(int i =0; i < n; i++)

coll .add(gen.nextO); return coll;

}

public static void main(String[] args) { Collection<Coffee> coffee = fill(

new ArrayList<Coffee>(). new CoffeeGenerator(). 4); for(Coffee с : coffee)

System.out.printin(c); Collection<Integer> fnumbers = fill(

new ArrayList<Integer>(), new FibonacciO. 12); for(int i fnumbers)

System.out.printO + \ ");

}

} /* Output: Americano 0 Latte 1 Americano 2 Mocha 3

1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. *///:-

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ fill() примСняСтся ΠΊ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°ΠΌ ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌ ΠΊΠ°ΠΊ для Ρ‚ΠΈΠΏΠ° Coffee, Ρ‚Π°ΠΊ ΠΈ для Integer.

ΠžΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ класс создаСт Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ для любого класса, ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‰Π΅Π³ΠΎ конструктором ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ объСма ΠΊΠΎΠ΄Π° Π² Π½Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния BasicGenerator:

//: net/mindview/uti1/BasicGenerator java // АвтоматичСскоС созданиС Generator для класса // с конструктором ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²) package net.mindview util;

public class BasicGenerator<T> implements Generator<T> { private Class<T> type;

public BasicGenerator(Class<T> type){ this.type = type; } public T nextО { try {

// ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ type являСтся public-классом, return type.newlnstance(); } catch(Exception e) {

throw new RuntimeException(e);

}

}

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ type: public static <T> Generator<T> create(Class<T> type) { return new BasicGenerator<T>(type).

}

} ///:-

Класс прСдоставляСт Π±Π°Π·ΠΎΠ²ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΡΠΎΠ·Π΄Π°ΡŽΡ‰ΡƒΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ класса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ (1) являСтся ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ BasicGenerator опрСдСляСтся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚Π΅, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ класс Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ доступа public, Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°ΡΡΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Π½Ρ‹ΠΌ доступом), ΠΈ (2) ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ конструктором ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ конструктором Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²). Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² BasicGenerator, слСдуСт Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ create() ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅ΠΌΡƒ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ create() позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ запись BasicGenerator.create(MyType.class) вмСсто Π±ΠΎΠ»Π΅Π΅ Π³Ρ€ΠΎΠΌΠΎΠ·Π΄ΠΊΠΎΠΉ конструкции new BasicGenerator<MyType>(MyType.class).

Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° рассмотрим простой класс с конструктором ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ:

//: generics/CountedObject.java

public class CountedObject {

private static long counter = 0; private final long id = counter++; public long id() { return id; }

public String toStringO { return "CountedObject " + id,} } ///:-

Класс CountedObject отслСТиваСт количСство созданных экзСмпляров ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ toString().

ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ BasicGenerator ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Generator для CountedObject:

//: generics/BasicGeneratorDemo java i mport net.mi ndvi ew.uti1.*.

public class BasicGeneratorDemo {

public static void main(String[] args) { Generator<CountedObject> gen =

BasicGenerator create(CountedObject.class), for(int i = 0; i < 5; i++)

System, out pri ntl n(gen. nextO);

}

} /* Output CountedObject 0 CountedObject 1 CountedObject 2 CountedObject 3 CountedObject 4 */// ~

Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° сниТаСт объСм ΠΊΠΎΠ΄Π°, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ для получСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Generator. Π Π°Π· ΡƒΠΆ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Java всС Ρ€Π°Π²Π½ΠΎ заставляСт вас ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Class, Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΎΠ΄Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для вычислСния Ρ‚ΠΈΠΏΠ° Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ create().

Π£ΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°ΠΌΠΈ

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ вычислСниС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ‚ΠΈΠΏΠΎΠ² Π² сочСтании со static-ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠΌ, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ„ΠΎΡ€ΠΌΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΡƒΡŽ Ρ€Π°Π½Π΅Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΉ Π² Π±ΠΎΠ»Π΅Π΅ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΌ статичСским ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ:

//β€’ net/mi ndvi ew/uti1/Tuple.java // Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°ΠΌΠΈ // с использованиСм вычислСния Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ‚ΠΈΠΏΠΎΠ² package net mindview.util,

public class Tuple {

public static <A,B> TwoTuple<A,B> tuple(A Π°. Π’ b) { return new TwoTuple<A,B>(a, b).

}

public static <A,B,C> ThreeTuple<A,B,C> tuple(A Π°. Π’ b. Π‘ с) {

return new ThreeTuple<A,B,C>(a, b, c):

}

public static <A,B,C.D> FourTuple<A,B,C.D> tuple(A Π°. Π’ b. Π‘ с. D d) {

return new FourTuple<A,B.C.D>(a. b. c. d).

}

public static <A,B,C.D,E>

FiveTuple<A,B,C,D,E> tuple(A Π°. Π’ b, Π‘ с, D d. E e) {

return new FiveTuple<A,B,C.D,E>(a, b. c. d. e);

}

} ///:-

А Π²ΠΎΡ‚ ΠΊΠ°ΠΊ выглядит обновлСнная вСрсия TupleTest.java для тСстирования Tuple.java:

//: generics/TupleTest2.java import net.mindview.util.*;

import static net.mindview.util.Tuple.*; ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ &

public class TupleTest2 {

static TwoTuple<String,Integer> f() { return tupleChi", 47);

}

static TwoTuple f2() { return tupleC'hi", 47); } static ThreeTuple<Amphibian,String,Integer> g() { return tuple(new AmphibianO, "hi", 47);

}

static

FourTuple<Vehicle,Amphibian,String,Integer> hO {

return tuple(new VehicleO, new AmphibianO, "hi", 47);

}

static

FiveTuple<Vehicle,Amphibian.String,Integer,Double> к О { return tuple(new VehicleO, new AmphibianO, "hi", 47, 11.1);

}

public static void main(String[] args) {

TwoTuple<String,Integer> ttsi = f(); System out.println(ttsi): System.out.println(f20); System.out.println(gO); System.out println(hO); System.out.println(kO);

}

} /* Output (hi, 47) (hi, 47)

( [email protected], hi, 47) ( [email protected], [email protected], hi. 47) ( [email protected], [email protected] hi. 47, 11.1) *///:-

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: f() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ TwoTuple, a f2() β€” ^ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ TwoTuple. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π½Π΅ Π²Ρ‹Π΄Π°Π΅Ρ‚ прСдупрСТдСния ΠΎ f2(), ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Β«ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΌΒ» стилС: Π² ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ смыслС проводится «восходящСС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅Β» Π΅Π³ΠΎ Π΄ΠΎ Π½Π΅ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ TwoTuple. Но, Ссли ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ f2() Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ TwoTuple, компилятор выдаст ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅.