Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Стирание типов в java, как проверить? / 8 сообщений из 8, страница 1 из 1
07.09.2017, 19:43
    #39517722
ll13
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
Изучаю java, в настоящий момент дошел до изучения обобщенных классов и методов.
В различной литературе сказано, что параметр типа будет удален при компиляции,
Переменные типа стираются и заменяются ограничивающими типами (или типом Object, если переменная не имеет ограничений)
Как это проверить? Как узнать какой код в результате будет выполнятся jvm ?

Создал простой обобщенный класс с параметром типа, скомпилировал в .class, затем декомпилировал с помощью http://www.javadecompilers.com
И... получил в точности свой исходный файл(!), включая обобщенный тип! Который вроде как должен был быть удален при компиляции?!! Никаких замен на Object нет и в помине!

Я что-то не так понял?
Друзья, помогите разобраться...
...
Рейтинг: 0 / 0
07.09.2017, 19:52
    #39517726
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
ll13,

В некоторых случаях Generic тип доступен через рефлексию. Например вот в таком:
Код: java
1.
2.
MyClass extends AbstractList<MyElement> {
}



А посмотреть на erasure можно разными способами. Например, написать Generic метод\класс, а рефлексией посмотреть сигнатуру - поля и методы и увидеть как Generic тип поменялся на "ограничивающий".

Для локальных переменных и смотреть особо нечего. Например, любая коллекция может содаржать объекты любого типа. Компилятор просто пытается вам не дать поместить их туда валидируя Generic. Но это не значит что вы не можете прикастить, подавить предупреждение и отгрести потом ClassCastException в рантайме.
...
Рейтинг: 0 / 0
07.09.2017, 22:29
    #39517802
ll13
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
Э... все равно не совсем понял(
Я пришел с другого языка, поэтому скорее всего не конца понимаю как работает компилятор и JVM, но хочу это понять...

Давайте , на примере, есть обобщенный класс:

public class genTest<T> {

private T value = null;

public genTest(T value) {
this.value= value;
}

public T getValue() {
return value;
}

@Override
public String toString() {
return "genTest{" + "value=" + value + '}';
}


public static void main(String[] args) {

genTest<String> pstr = new Pair<>("aaa"");
System.out.println(pstr);

genTest<Integer> pint = new Pair<>(333);
System.out.println(pint);
}


После его компиляции я получу файл genTest.class содержащий байт-код, который и будет выполнять виртуальная машина java.
В литературе пишут, что виртуальная машина java никаких обобщенных типов знать не знает и компилятор при создании genTest.class сотрет все параметры типов и сделает все соответствующие подстановки.
Таким образом genTest.class уже содержит обычные классы и не содержит обобщенных. Я правильно рассуждаю?
Далее я декомпилирую genTest.class с помощью http://www.javadecompilers.com и получаю точно такой же исходный файл genTest.java, который содержит обобщенный класс! Откуда он там, если он уже был "преобразован" компилятором?!
...
Рейтинг: 0 / 0
07.09.2017, 22:36
    #39517808
ll13
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
Следует читать:
ll13 ...
genTest<String> pstr = new genTest<>("aaa"");
System.out.println(pstr);

genTest<Integer> pint = new genTest<>(333);
System.out.println(pint);
...
...
Рейтинг: 0 / 0
08.09.2017, 05:44
    #39517887
guest2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
ll13,

Попробуй скомпилировать этот класс:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
import java.util.List;

class GenTest {

    public void doSomething(List<Integer> list) {
    }

    public void doSomething(List<String> list) {
    }

}
...
Рейтинг: 0 / 0
08.09.2017, 07:20
    #39517906
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
ll13В литературе пишут, что виртуальная машина java никаких обобщенных типов знать не знает и компилятор при создании genTest.class сотрет все параметры типов и сделает все соответствующие подстановки.
Это очень грубое приближение. На самом деле всё намного сложнее.
http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

Вот пример того что JVM знает о генериках.
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getGenericInterfaces--
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getGenericSuperclass--

ll13Таким образом genTest.class уже содержит обычные классы и не содержит обобщенных. Я правильно рассуждаю?

В целом, да. Но вы местами делаете выводы основываясь на ограниченных знаниях.

ll13Далее я декомпилирую genTest.class с помощью http://www.javadecompilers.com и получаю точно такой же исходный файл genTest.java, который содержит обобщенный класс!
Потому что вы не правильно понимаете erasure.
public class GenTest<T> -> эта информация никуда не девается. Java знает что GetTest содержит в себе генерик. Это часть сигнатуры класса.
GenTest<String> test = new GenTest<>(); - а вот эта информация о том что переменная test ограничена не только классом GetTest но и его генерик типом String - вот эта информация и теряется. В рантайме у нас есть только GetTest, который может работать с любым типом объекта.

ll13Откуда он там, если он уже был "преобразован" компилятором?!
Ну, компилятор сохраняет в мета описании класса больше информации. Я привел выше методы. Это она и есть.
...
Рейтинг: 0 / 0
08.09.2017, 18:49
    #39518407
ll13
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
guest2,

Я знаю что не скомпилируется... потому-что параметры методов будут одного и того же типа List
...
Рейтинг: 0 / 0
08.09.2017, 18:56
    #39518411
ll13
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Стирание типов в java, как проверить?
Blazkowicz,

Большое спасибо за разъяснения и полезные ссылки. Буду разбираться дальше.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Стирание типов в java, как проверить? / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]