[java] ну это ваще пипец...

psihodog

Ну почему нельзя писать:
void f(Templ<? extends A super B>)
?

livemix

а зачем?

psihodog

ну чтобы и читать в контейнер и писать одновременно.
главное, это ведь просто должно реализовываться и логично этой хрени существовать.

Dasar

Своими словами скажи, что ты хотел добиться такой записью? а то я плаваю в Java-синтаксисе.

anton7805

имхо, ты java не в ту сторону копаешь. Контейнеры в java.utils вполне заменяют дженерики

psihodog

Метод, у которого аргумент -- класс параметризованный классом, который в иерархическом дереве находится на заданном отрезке [A,B] (или [B,A] -- как кому угодно). Вроде так.

psihodog

не понял мысль...

Dasar

> на заданном отрезке [A,B]
Вот это совсем не понял.

psihodog

Это все классы, которые являются родителями для B и потомками для A (включая сами классы A и B).
В нынешнем синтаксисе можно только задавать отрезки [Object,A] и [A,\infty].

rosali


> на заданном отрезке [A,B]
Вот это совсем не понял.
Ну, является потомком A и предком B.
Дело в том, что у массивов-на-чтение действует ковариантный закон, то есть если A1<A2, то и A1[] < A2[]. А вот для массивов-на-запись закон контрвариантный!
Я недавно в Си на похожую тему прикол однаружил. (A *) можно неявно скастить в (const A * и к этому уже все привыкли, так вот оказывается неявно скастить (A * *) в (const A * *) нельзя! Все подумайте на досуге почему

Dasar

> Это все классы, которые являются родителями для B
С трудом понимаю смысл этого ограничения.
Зачем такое надо?

psihodog

Ну вот написал... я нутром чую, что это верно, правда при словах ковариантный/контравариантный, мне смутно вспоминается дифгем, а дальше этого дело не идёт.
Популярно могу объяснить вот как:
class Templ<T> {
T a;
T f {...}
void f(T b) {...}
}
	static void f(Templ<? extends B> t) {
B b;
b= t.f; // ok
// t.f(b); // bad
}

static void g(Templ<? super C> t) {
C c= new C;
// c= t.f; // bad
t.f(c); // ok
}

Dasar

> вот для массивов-на-запись закон контрвариантный!
Это понятно.
Не совсем было понятно - когда появляется ограничение, что тип должен быть предком данного типа..
Но сейчас дошло, что при чтении - если реальный тип B, то отдавать мы его можем только, как один из его базовых типов.

kamputer

>Я недавно в Си на похожую тему прикол однаружил. (A *) можно неявно скастить в (const A * и к этому уже все привыкли, так вот оказывается неявно скастить (A * *) в (const A * *) нельзя! Все подумайте на досуге почему
"С++ Gotchas",

rosali

Зачем такое надо?
  
class A1 extends A {...}
A1[] x = new A1[10];
f(x);

void f(A[] x) {
x[0] = new A; //exception!
}
Вот там где "exception!" там в Java-е реально происходит exception, потому что любое присваивание в массив подразумавает динамическую проверку типизации, можно присвоить или нет. Для языка со статической типизацией это nonsence, но разработчики на это пошли, очень уж многие искренне верят, что если у f параметр имеет тип A[], то можно подать в качестве аргумента A1[].
Так вот чтобы этого overhead-а избежать можно ввести вместо понятия "массив из A
(и потомков?)" понятие "контейнер из элементов от A до B", и один контейнер будет кастится в другой есть соответствующие отрезки друг в друга вложены. А в динамике проверки типизации не будет ни при записи ни при чтении...

psihodog

очень уж многие искренне верят, что если у f параметр имеет тип A[], то можно подать в качестве аргумента A1[]

Кстати, а что в этом реально плохого? Я, кажется, где-то наталкивался на обсуждение, но там было слишком много английских слов и я устал читать.

bastii

В Джава по-любому проверка будет, с дженериками ее вставляет компилятор.

psihodog

Так что можете мне сказать по этому поводу?
очень уж многие искренне верят, что если у f параметр имеет тип A[], то можно подать в качестве аргумента A1[]
Кстати, а что в этом реально плохого?

rosali

Ну вот то что я написал собственно и плохо

class A1 extends A {
public int m { return 1; }
}

void f(A[] x) {
x[0] = new A; //либо здесь глупость: нельзя в A[] положить new A?
}

A1[] x = new A1[10];
f(x);
x[0]->m; //либо здесь: нет такого метода в классе A!
В Java-е выбрана первая глупость...

Dasar

Первая глупость более логичная
Оставить комментарий
Имя или ник:
Комментарий: