Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Generics или я опять что-то не понял ... / 12 сообщений из 12, страница 1 из 1
30.10.2013, 17:18:20
    #38447122
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
package generics.simple;

import java.util.ArrayList;

public class A
{
 public A add(A a) {
 	return null;
 }
}

public class B<T extends A>
{
 ArrayList<T> a;
 
	public T some(T arg) {
        return a.get(0);               // все good - он типа "T"
 	return a.get(0).add(arg);  // error - из "A" "T" не кастится 
        return (T)(a.get(0).add(arg));  // unchecked cast
 }
}



Вот последние два варианта ретёрна мне как-то не ясны ... Почему error или warning, если стирание происходит до типа "A" ?
...
Рейтинг: 0 / 0
30.10.2013, 17:27:04
    #38447155
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Из-за того что вы сделали chained вызов, похоже и запутались.
"error - из "A" "T" не кастится " - Метод add возвращает тип A, метод some возвращает наследника A, например B. Очевидно что метод add может вернуть другого наследника, например С, который к B не приводится.
Отсюда и "unchecked cast"
...
Рейтинг: 0 / 0
30.10.2013, 17:43:31
    #38447187
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Blazkowicz,
Метод add возвращает тип AОчевидно что метод add может вернуть другого наследникаКак это другого, он же не параметризованный? Что А к Т не приведется без ругани и так понятно, это ж даункаст.
...
Рейтинг: 0 / 0
30.10.2013, 17:44:51
    #38447192
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Blazkowicz,

Хммм... Если B это "B", то "B" не наследник "A" ... Если "A" это все-таки класс, а не интерфейс, то все наследники "А" должны приводиться к "A" ?
...
Рейтинг: 0 / 0
30.10.2013, 17:48:01
    #38447202
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
_usa__83_,
то все наследники "А" должны приводиться к "A" ?у вас же в примере наоборот, вы приводите А к его наследнику, к Т
...
Рейтинг: 0 / 0
30.10.2013, 17:56:50
    #38447235
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
javapecker,

Во путаница (у меня) ...

1. T extends A - значит что подстановочный тип может быть либо "A" либо его наследником ...
2. Если на этапе выполнения я подпихиваю какой-нибудь экземпляр класса "C" (class C extends A ...) то в методе some() должен вызываться метод
add() класса "C" (?) который может вернуть какой-нить экземпляр класса "C" (?) но который должен приводиться таки к "A" ?

кхе-кхе ...
...
Рейтинг: 0 / 0
30.10.2013, 18:06:55
    #38447265
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
_usa__83_,
Если на этапе выполнения я подпихиваю какой-нибудь экземпляр класса "C" (class C extends A ...) то в методе some() должен вызываться метод
add() класса "C"(?) который может вернуть какой-нить экземпляр класса "C" (?) но который должен приводиться таки к "A" ? Разумеется С приведется к А. Но у метода some возвращаемое значение не А, а некоторый тип Т, унаследованный от А. Пусть А это посуда, Т это сковородка, С это кастрюля. Сковородка это посуда, кастрюля это посуда, но кастрюля это не сковородка. Если ваш класс будет параметризован сковородкой, а метод add вернет кастрюлю, то вам придется приводить кастрюлю к сковородке. Конечно компилятор на это ругается.
...
Рейтинг: 0 / 0
30.10.2013, 18:26:11
    #38447309
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
javapecker,

С кастрюлями и сковородками очень наглядно (правда), но суть все же ускальзает, может я путаю этап компиляции и выполнения ?
В приведенном коде класс "B" параметризован "A" или его наследниками, значит в момент создания тип содержимого контейнера определен четко:
если сковородка - значит сковородка ... Когда вызывается метод add() у фактического элемента ArrayList<Сковородка> это будет метод с какой сигнатурой (Cковородка add(Cковородка a); A add(A a); Cковородка add(A a); Кастрюля add(Сковородка а) и .т.д.)? т.е. с чего бы ему возвращать иного потомка класса "A" вне цепочки иерархии от "A" до сковородка? Понятно что это можно реализовать но только ли в этом проблема ?

уф))
...
Рейтинг: 0 / 0
30.10.2013, 18:36:40
    #38447324
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
_usa__83_,это будет метод с какой сигнатурой
Исходные данные - есть класс А и есть B. Больше нет ничего. У вас параметр T extends A. Идем в класс А и смотрим сигнатуру add. Видим A add(A a). Таким образом, все что знает B о методе add, это что он вернет A. Все что знает B о параметре Т - то что это наследник А. поэтому в методе some() выполняется приведение А к T extends A, то есть родителя к наследнику - это даункаст, и вы должны сами решать, можно так делать или нет.
...
Рейтинг: 0 / 0
30.10.2013, 21:03:47
    #38447453
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Код: java
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.
package generics.simple;

import java.util.ArrayList;

public class A
{
 public A add(A a) {
 	return new A1();
 }
}

class A1 extends A{};
class A2 extends A{};

public class B<T extends A>
{
 ArrayList<T> a;
 
	public T some(T arg) {
        return a.get(0);               // все good - он типа "T"
 	return a.get(0).add(arg);  // error - из "A" "T" не кастится 
        return (T)(a.get(0).add(arg));  // unchecked cast
 }
}

B<A2> b = new B<A2>();
b.a = new ArrayList<A2>();
b.a.add(new A2());
A2 a2 = b.some(); //Тут имеем ClassCastException, потому что A1 это не A2
...
Рейтинг: 0 / 0
30.10.2013, 22:35:04
    #38447523
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Blazkowicz,

Угу, пасиба всем, сваял только аналогичное ... Действительно ClassCastException ...

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
package test;

public class GenTest<T extends A> 
{
 public T get(T arg) {
  T c=arg;
  System.out.println("Before: "+c.getClass().getName());
  c = (T)arg.get(); // Warning: unchecked cast
  System.out.println(" After: "+c.getClass().getName());
  if (c instanceof C)
   ((C)c).print();	 
  return c;
  }
 
 
 
 public static void main(String[] args) {
  GenTest<A> a=new GenTest<>();
  System.out.println("Trying to cast \"C\" from \"B\"");
  B b=(B)a.get(new B());
  System.out.println("\n\nTrying to cast \"B\" from \"C\"");
  a.get(new C());
 }
}



javapecker - Вы правы, от формализма синтаксиса не уйти, пример, как показали, сочиним ...
...
Рейтинг: 0 / 0
30.10.2013, 22:36:53
    #38447527
_usa__83_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics или я опять что-то не понял ...
Blazkowicz,

P.s. у Вас пример удачнее
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Generics или я опять что-то не понял ... / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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