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

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

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

Главная ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° для примСнСния стирания Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΎ позволяСт ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚. Π­Ρ‚Π° концСпция часто называСтся ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ. НавСрноС, Π² идСальном ΠΌΠΈΡ€Π΅ парамСтризация Π±Ρ‹Π»Π° Π±Ρ‹ Π²Π½Π΅Π΄Ρ€Π΅Π½Π° Π²Π΅Π·Π΄Π΅ ΠΈ ΠΏΠΎΠ²ΡΡŽΠ΄Ρƒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ программисту, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ ΠΏΠΈΡˆΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, приходится ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ с ^ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ, написанными Π΄ΠΎ Java SE5. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π°Π²Ρ‚ΠΎΡ€Ρ‹ этих Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Π½Π°ΠΌΠ΅Ρ€Π΅Π½Ρ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ свой ΠΊΠΎΠ΄ ΠΈΠ»ΠΈ ΡΠΎΠ±ΠΈΡ€Π°ΡŽΡ‚ΡΡ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.

Из-Π·Π° этого ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡƒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Java приходится ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΡƒΡŽ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ (ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΈ Ρ„Π°ΠΉΠ»Ρ‹ классов ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ Π·Π°ΠΊΠΎΠ½Π½Ρ‹ΠΌΠΈ ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ свой ΠΏΡ€Π΅ΠΆΠ½ΠΈΠΉ смысл), Π½ΠΎ ΠΈ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΡƒΡŽ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ β€” Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΌΠΎΠ³Π»ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ Π² собствСнном Ρ‚Π΅ΠΌΠΏΠ΅, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ ΠΈΡ… парамСтризация Π½Π΅ влияла Π±Ρ‹ Π½Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ зависящСго ΠΎΡ‚ Π½Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’Ρ‹Π±Ρ€Π°Π² эту Ρ†Π΅Π»ΡŒ, ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠΈ Java ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π³Ρ€ΡƒΠΏΠΏΡ‹, Ρ€Π°Π±ΠΎΡ‚Π°Π²ΡˆΠΈΠ΅ Π½Π°Π΄ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, Ρ€Π΅ΡˆΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ СдинствСнным ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ‹ΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ являСтся стираниС, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π΅ Π½Π΅ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚-Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΌΡƒ ΠΊΠΎΠ΄Ρƒ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ ΡΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ стирания

Π˜Ρ‚Π°ΠΊ, Π³Π»Π°Π²Π½Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ для примСнСния стирания являСтся процСсс ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π° с Π½Π΅ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΈ интСграция ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² язык Π±Π΅Π· Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ. Π‘Ρ‚ΠΈΡ€Π°Π½ΠΈΠ΅ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ^ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΏΠΎΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ² ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ свой ΠΊΠΎΠ΄ с использованиСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Однако Π·Π° стираниС приходится Ρ€Π°ΡΠΏΠ»Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒΡΡ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² опСрациях, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… явно задСйствованы Ρ‚ΠΈΠΏΡ‹ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния β€” прСобразования Ρ‚ΠΈΠΏΠΎΠ², instanceof ΠΈ выраТСния new. Вся информация ΠΎ Ρ‚ΠΈΠΏΠ°Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² тСряСтся, ΠΈ ΠΏΡ€ΠΈ написании ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π²Π°ΠΌ придСтся постоянно Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ сСбС ΠΎΠ± этом. Допустим, Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π°

class Foo<T> { Π’ var;

}

ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ создании экзСмпляра Foo:

Foo<Cat> f = new Foo<Cat>(),

ΠΊΠΎΠ΄ class Foo Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Cat. Бинтаксис создаСт Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»Π΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ Π’ подставляСтся ΠΏΠΎΠ²ΡΡŽΠ΄Ρƒ Π²Π½ΡƒΡ‚Ρ€ΠΈ класса. Но Π½Π° самом Π΄Π΅Π»Π΅ это Π½Π΅ Ρ‚Π°ΠΊ, ΠΈ ΠΏΡ€ΠΈ написании ΠΊΠΎΠ΄Π° для класса Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ постоянно Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ сСбС: «НСт, это всСго лишь ObjectΒ».

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, стираниС ΠΈ миграционная ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Π·Π° использованиСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ТСсткий, ΠΊΠ°ΠΊ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹:

//: generics/ErasureAndlnheritance.java

class GenericBase<T> { private T element;

public void set(T arg) { arg = element; } public T get О { return element. }

}

class Derivedl<T> extends GenericBase<T> {}

class Derived2 extends GenericBase {} // Π‘Π΅Π· ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ

// class Derived3 extends GenericBase<?> {}

// Бтранная ошибка.

// ΠžΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ Π½Π΅ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄Π΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ : ?

// трСбуСтся- класс ΠΈΠ»ΠΈ интСрфСйс Π±Π΅Π· ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ

public class ErasureAndlnheritance { @SuppressWarni ngs("unchecked") public static void main(String[] args) { Derived2 d2 = new Derived2(); Object obj = d2.get(); d2.set(obj); // ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅!

}

} ///

Derived2 наслСдуСт ΠΎΡ‚ GenericBase Π±Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΈ компилятор Π½Π΅ Π²Ρ‹Π΄Π°Π΅Ρ‚ ΠΏΡ€ΠΈ этом Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ. ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ выводится ΠΏΠΎΠ·ΠΆΠ΅, ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ set().

Для подавлСния этого прСдупрСТдСния Π² Java сущСствуСт Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Π°, привСдСнная Π² листингС (Π΄ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π° Java SE5 ΠΎΠ½Π° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π»Π°ΡΡŒ):

@SuppressWarnings("unchecked")

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

Ошибка, выдаваСмая Π² Derived3, ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ компилятор рассчитываСт ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Β«ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉΒ» Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс.

Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΊ этому Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ усилия Π½Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ограничСниями, Ссли Π²Ρ‹ Π½Π΅ ΠΆΠ΅Π»Π°Π΅Ρ‚Π΅ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° ΠΊΠ°ΠΊ простой Object, β€” ΠΈ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π² остаткС? Π“ΠΎΡ€Π°Π·Π΄ΠΎ большС Ρ…Π»ΠΎΠΏΠΎΡ‚ ΠΏΡ€ΠΈ Π³ΠΎΡ€Π°Π·Π΄ΠΎ мСньшС, пользС ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ Π² языках Π²Ρ€ΠΎΠ΄Π΅ Π‘++, Ada ΠΈΠ»ΠΈ Eiffel. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, это вовсС Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ эти языки Π² Ρ†Π΅Π»ΠΎΠΌ эффСктивнСС Java Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ Π·Π°Π΄Π°Ρ‡ программирования, Π° Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ лишь ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΡ… ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ² ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ большСй Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒΡŽ ΠΈ ΠΌΠΎΡ‰ΡŒΡŽ, Ρ‡Π΅ΠΌ Π² Java.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π½Π° Π³Ρ€Π°Π½ΠΈΡ†Π°Ρ…

ΠŸΠΎΠΆΠ°Π»ΡƒΠΉ, самый странный аспСкт ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, обусловлСнный стираниСм, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² возмоТности прСдставлСния Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ бСссмыслСнных Π²Π΅Ρ‰Π΅ΠΉ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

//: generics/ArrayMaker.java

import java.lang.reflect.*;

import java.util.*;

public class ArrayMaker<T> { private Class<T> kind;

public ArrayMaker(Class<T> kind) { this.kind = kind; } @SuppressWarni ngs("unchecked") T[] create(int size) {

return (T[])Array.newInstance(kind, size);

}

public static void main(String[] args) { ArrayMaker<String> stringMaker =

new ArrayMaker<String>(String.class); String[] stringArray = stringMaker.create(9); System.out.pri ntin(Arrays.toStri ng(stri ngArray));

}

} /* Output;

[null, null, null. null. null. null. null. null, null]

*///:-

НСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ kind хранится Π² Π²ΠΈΠ΄Π΅ Class<T>, стираниС ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ фактичСски ΠΎΠ½ хранится Π² Π²ΠΈΠ΄Π΅ Class Π±Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ с Π½ΠΈΠΌ ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ создании массива) Array. newlnstance() Π½Π΅ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎ Ρ‚ΠΈΠΏΠ΅, ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅ΠΌΠΎΠΉ kind. ΠœΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ смоТСт Π²Ρ‹Π΄Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΠΉ прСобразования Ρ‚ΠΈΠΏΠ°, Π° это ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Ρ‹Π΄Π°Ρ‡Π΅ прСдупрСТдСния, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π²Π°ΠΌ Π½Π΅ удастся ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒΡΡ.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: для создания массивов Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ рСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Array.newlnstance().

Если вмСсто массива создаСтся Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, ситуация мСняСтся:

//: generics/ListMaker.java

import java util.*;

public class ListMaker<T> {

List<T> create О { return new ArrayList<T>(); } public static void main(String[] args) {

ListMaker<String> stringMaker= new ListMaker<String>(); List<String> stringList = stringMaker.createO;

}

} ///:-

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π½Π΅ Π²Ρ‹Π΄Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ, хотя ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ <Π’> Π² new ArrayList<T>() Π²Π½ΡƒΡ‚Ρ€ΠΈ create() удаляСтся β€” Π²ΠΎ врСмя выполнСния <Π’> Π²Π½ΡƒΡ‚Ρ€ΠΈ класса Π½Π΅Ρ‚, поэтому здСсь Π΅Π³ΠΎ присутствиС выглядит бСссмыслСнным. Однако Ссли Π²Ρ‹ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ эту идСю Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚Π΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² new ArrayList(), компилятор выдаст ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅.

Но Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»ΠΈ этот элСмСнт Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла? Π§Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, Ссли ΠΌΡ‹ помСстим Π² список нСсколько ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²ΠΎΠ·Π²Π°Ρ‚ΠΈΠΌ Π΅Π³ΠΎ?

II: generics/Fi1ledListMaker java

import java.util.*;

public class FilledListMaker<T> { List<T> create(T t, int n) {

List<T> result = new ArrayList<T>(); for(int i = 0: i < n; i++)

result.add(t); return result:

}

public static void main(String[] args) {

FilledListMaker<String> stringMaker =

new Fi11edListMaker<String>(); List<String> list = stringMaker.createC'Hello", 4): System.out.pri ntln(1i st);

}

} /* Output:

[Hello, Hello. Hello. Hello]

*lll:~

Π₯отя компилятор Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‚ΡŒ ΠΎ Π’ Π² create(), ΠΎΠ½ всС Ρ€Π°Π²Π½ΠΎ способСн ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ β€” Π½Π° стадии компиляции β€” Ρ‡Ρ‚ΠΎ заносимыС Π² result ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ Ρ‚ΠΈΠΏ Π’ ΠΈ ΡΠΎΠ³Π»Π°ΡΡƒΡŽΡ‚ΡΡ с ArrayList<T>. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, нСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ стираниС удаляСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ фактичСском Ρ‚ΠΈΠΏΠ΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠ»ΠΈ класса, компилятор всС Ρ€Π°Π²Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ использования Ρ‚ΠΈΠΏΠ° Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ ΠΈΠ»ΠΈ классС.

Π’Π°ΠΊ ΠΊΠ°ΠΊ стираниС удаляСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅Π»Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Π½Π° стадии выполнСния ΠΎΡΠΎΠ±ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ ΠΏΡ€ΠΈΠΎΠ±Ρ€Π΅Ρ‚Π°ΡŽΡ‚ Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ β€” Ρ‚ΠΎΡ‡ΠΊΠΈ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. ИмСнно Π² этих Ρ‚ΠΎΡ‡ΠΊΠ°Ρ… компилятор выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈ вставляСт ΠΊΠΎΠ΄ прСобразования. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ^ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

// generics/SimpleHolder.java

public class SimpleHolder { private Object obj;

public void set(Object obj) { this.obj = obj; } public Object get О { return obj; } public static void main(String[] args) {

SimpleHolder holder = new SimpleHolder().

holder set("Item"),

String s = (String)holder getO:

}

} ///-

Π”Π΅ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ javap -с SimpleHolder, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ (послС рСдактирования):

public

void set(java lang Object);

0

aload_0

1:

aload 1

2:

putfield #2; II ПолС obj.Object;

5.

return

public

java lang.Object getO.

0;

aload 0

1-

getfield #2; II ПолС obj-Object,

4

areturn

public

static void main(java 1ang.String[]);

0:

new #3, // Класс SimpleHolder

3-

dup

4:

invokespecial #4; // ΠœΠ΅Ρ‚ΠΎΠ΄ "<init>".()V

7.

astore_l

8-

aload 1

9.

ldc #5; II String Item

11

invokevirtual #6; // ΠœΠ΅Ρ‚ΠΎΠ΄ set (Object;)V

14:

aload_l

15.

invokevirtual #7, // ΠœΠ΅Ρ‚ΠΎΠ΄ get:()Object:

18;

checkcast #8, //'Класс java/lang/String

21:

astore_2

22.

return

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ set() ΠΈ get() просто Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ ΠΈ Ρ‡ΠΈΡ‚Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ провСряСтся Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ Π²Ρ‹Π·ΠΎΠ²Π° get().

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·Π°Ρ†ΠΈΡŽ Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚:

II: generics/GenericHolder.java

public class GenericHolder<T> { private T obj,

public void set(T obj) { this.obj = obj; } public T get О { return obj; } public static void main(String[] args) { GenericHolder<String> holder =

new GenericHolder<String>(); holder.set("Item"); String s = holder.get О;

}

ΠΠ΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ прСобразования Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ значСния get() ΠΎΡ‚ΠΏΠ°Π»Π°, Π½ΠΎ ΠΌΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ значСния, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ set(), провСряСтся Π²ΠΎ врСмя компиляции. Π‘ΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π±Π°ΠΉΡ‚-ΠΊΠΎΠ΄:

public void set(java.lang.Object);

0:

aload_0

1:

aload_l

2:

putfield #2; // ПолС obj:0bject;

5:

return

public java.lang.Object getO;

0:

aload_0

1:

getfield #2; // ПолС obj:0bject;

4:

areturn

public static void main(java.lang.String[]);

0.

new #3; // Класс GenericHolder

3:

dup

4:

invokespecial #4; // ΠœΠ΅Ρ‚ΠΎΠ΄ "<init>"-()V

7:

astore_l

8:

aload_l

9:

ldc #5; // String Item

11