LINUX.ORG.RU
ФорумTalks

[java][г]Маразматические глюки.

 


0

0

Есть простенький код:

import java.util.Arrays;
import java.util.List;
public class Main {
    public static void main(String[] args) {
      Container cont0 = new Container();
      for(String s : cont0.getStrings()){
        System.out.println(s);
      }
    }
}
class Container<T> {
  public T getType(){
    return null;
  }
  public List<String> getStrings(){
    return Arrays.asList("1", "2", "str");
  }
}

Компилируем.... и получаем

Main.java:6: incompatible types
found   : java.lang.Object
required: java.lang.String
      for(String s : cont0.getStrings()){
                                     ^
1 error

Это не бага, а фишка, только как эти **** которые такие фишки придумали объяснят свои затейства (в багтреккере наверняка это есть но непонятно как найти)?

ps. Пойти что ли в церковь микрософта и поставить черную свечку за тех кто реализовал генерики в яве?

★★☆

Последнее исправление: wfrr (всего исправлений: 1)

Ответ на: комментарий от shty

Этож пропаганда того что яву либо пора обновлять либо выкидывать.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Он указан лишь для случаев, когда генерики вообще применимы.

вы страдаете амозглием. изучите сигнатуру метода, уважаемый.

Чего и вам желаю:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.2

Two methods have the same signature if they have the same name and argument types.

Сигнатуры List<String> getStrings() и List getStrings() и даже Object getStrings() одинаковы.

> Неяное приведение типов (то, что подставляет компилятор) - это результат работы генериков.

Уважаемый, у вас в голове каша. Изучите соответствующую литературу.

Речь шла о неявном приведении типов вниз. Ваш for(String s : cont0.getStrings()) может работать исключительно благодаря такому приведению.

> Как только вы объявили cont0 как raw type от Container<T> вы сказали компилятору примерно следующее: «я Выферр не знаю откуда я получу ссылку на Container. поэтому считаю важным сообщить, что обращаться с cont0 следует так же, как в Java 1.4.2».

Фигасе, вы разговариваете с компилятром. А толчку вы не приказываете поглотить результат ваших умственных потуг? Изучите таки спецификацию, и не смешите меня вашими домыслами.

Да, весь ваш код - это набор инструкций для компилятора. Или вы изобрели компилятор, который пишет программы сам? Что касается спецификации Java, то вам самому следует её изучить. По крайней мере ссылки, которые были в этой теме.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Сигнатуры List<String> getStrings() и List getStrings() и даже Object getStrings() одинаковы.

Это даже не буковедство, а буксоё**тво 8) Или вы прикидываетесь идиотом? У вас это хорошо получается, врачи не отличат.

Речь шла о неявном приведении типов вниз. Ваш for(String s : cont0.getStrings()) может работать исключительно благодаря такому приведению.

Я вам еще не говорил что у вас в голове каша? Там, уважаемый явно указано что String, или у вас проблемы, с проблемами к врачу, уважаемый.

Да, весь ваш код - это набор инструкций для компилятора. Или вы изобрели компилятор, который пишет программы сам? Что касается спецификации Java, то вам самому следует её изучить. По крайней мере ссылки, которые были в этой теме.

Вам я смотрю нравится нести чушь с серьезным видом, особенно с учетом того что ссылки на спецификацию привели вы но совершенно не по теме, как и положено уважающему себя троллю.

wfrr ★★☆
() автор топика
Ответ на: комментарий от phoenix

Читать топик, тут все написано.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

To facilitate interfacing with non-generic legacy code, it is also possible to use as a type the erasure (§4.6) of a parameterized type (§4.5). Such a type is called a raw type.

More precisely, a raw type is define to be either:

* The name of a generic type declaration used without any accompanying actual type parameters. * Any non-static type member of a raw type R that is not inherited from a superclass or superinterface of R.

Твой случай первый

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

это для размышления о том, почему код в теме не хороший.

It is a compile-time error to attempt to use a type member of a parameterized type as a raw type.

это почему компилятор ругается.

Да если бы raw types уже запретили, было бы удобнее ;)

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

код в теме не хороший.

Иван очевиднев?

код в теме не хороший.

Там общий случай описан типа:

List list = ...;
for(String s : list){ // вот тут и будет "use a type member of a parameterized type as a raw type."
}

а в топике возвращаемый методом резульат отнюдь не raw type, по логике 8)

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> > Сигнатуры List<String> getStrings() и List getStrings() и даже Object getStrings() одинаковы.

Это даже не буковедство, а буксоё**тво 8) Или вы прикидываетесь идиотом? У вас это хорошо получается, врачи не отличат.


Если вы не знаете, что такое сигнатура метода, читайте спецификацию Java перед сном. Для того, чтобы говорить что-то осмысленное, нужно хотябы понимать о чём говоришь.

> Речь шла о неявном приведении типов вниз. Ваш for(String s : cont0.getStrings()) может работать исключительно благодаря такому приведению.


Я вам еще не говорил что у вас в голове каша? Там, уважаемый явно указано что String, или у вас проблемы, с проблемами к врачу, уважаемый.


У вас пробел в образовании. List#get(int) и Iterator#next() всегда возвращают Object. Этим достигается совместимость со старым кодом, который может их вызывать. Параметризация добавляет неявное приведение вниз возвращённой ссылки, в вашем случае к String. Происходит это только в том случае, когда генерики применимы. Но для вашей cont0 они не применимы, поскольку вы сами объявили её как raw type от Collection<T>.

> Да, весь ваш код - это набор инструкций для компилятора. Или вы изобрели компилятор, который пишет программы сам? Что касается спецификации Java, то вам самому следует её изучить. По крайней мере ссылки, которые были в этой теме.


Вам я смотрю нравится нести чушь с серьезным видом, особенно с учетом того что ссылки на спецификацию привели вы но совершенно не по теме, как и положено уважающему себя троллю.


Чушью это выглядит лишь для таких упёртых болванов как вы.

bbk123 ★★★★★
()
Ответ на: комментарий от wfrr

> а в топике возвращаемый методом резульат отнюдь не raw type, по логике 8)

Лишь по беличьей логике. cont0 - raw type от Collection<T>. Метод getStrings() нестатический, следовательно raw type-ный cont0.getStrings() возвращает List, а не List<String>.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Для того, чтобы говорить что-то осмысленное, нужно хотябы понимать о чём говоришь.

Эти слова, да вам бы в уши.

У вас пробел в образовании. List#get(int) и Iterator#next() всегда возвращают Object. Этим достигается совместимость со старым кодом, который может их вызывать. Параметризация добавляет неявное приведение вниз возвращённой ссылки, в вашем случае к String

У вас пробел в голове, уважаемый 8), и дохрена ошибок:

1) они возвращают тот объект что в них хранится, удивлены?

2) происходит явное преобразование типов 8)

Происходит это только в том случае, когда генерики применимы. Но для вашей cont0 они не применимы, поскольку вы сами объявили её как raw type от Collection<T>.

Вы уважаемый, видимо курите много, посмотрите еще раз на возвращаемый тип метода 8), а то право, мне кажется что в дурдом провели инет.

Чушью это выглядит лишь для таких упёртых болванов как вы.

Ай-яй, вы уже меня оскорбляете, больше ваш воспаленный маразум не родил аргументов?

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Ай-яй, вы уже меня оскорбляете

Ты этого так долго добивался, так что не притворяйся, что тебе не нравится.

tailgunner ★★★★★
()
Ответ на: комментарий от wfrr

> У вас пробел в образовании. List#get(int) и Iterator#next() всегда возвращают Object. Этим достигается совместимость со старым кодом, который может их вызывать. Параметризация добавляет неявное приведение вниз возвращённой ссылки, в вашем случае к String

У вас пробел в голове, уважаемый 8), и дохрена ошибок:

Какой ужас.

1) они возвращают тот объект что в них хранится, удивлены?

Они возвращают ссылку на объект. Удивлены? Тип этого объекта после компиляции неизвестен. Снова удивлены? Поэтому если посмотреть на код после компиляции вы увидете, что возвращается Object.

2) происходит явное преобразование типов 8)

Явное преобразование типов вниз происходит только если вы написали этот тип в круглых скобках. Генерики делают это неявно.

Откомпилируйте и дизассемблируйте следующий просто код:

	public static void main(String[] args) {
		String s;
		List<String> list = new ArrayList<String>();
		List list2 = list;

		s = list.get(0);
		s = (String) list2.get(0);
	}

Вы увидете следующий байткод:

public static void main(java.lang.String[]);
  Code:
   0:	new	#2; //class java/util/ArrayList
   3:	dup
   4:	invokespecial	#3; //Method java/util/ArrayList."<init>":()V
   7:	astore_2
   8:	aload_2
   9:	astore_3
   10:	aload_2
   11:	iconst_0
   12:	invokeinterface	#4,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
   17:	checkcast	#5; //class java/lang/String
   20:	astore_1
   21:	aload_3
   22:	iconst_0
   23:	invokeinterface	#4,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
   28:	checkcast	#5; //class java/lang/String
   31:	astore_1
   32:	return

> Происходит это только в том случае, когда генерики применимы. Но для вашей cont0 они не применимы, поскольку вы сами объявили её как raw type от Collection<T>.

Вы уважаемый, видимо курите много, посмотрите еще раз на возвращаемый тип метода 8), а то право, мне кажется что в дурдом провели инет.

Посмотрите ещё раз что такое raw types и перестаньте нести чушь. У raw types никакой параметризации нет и быть не может.

> Чушью это выглядит лишь для таких упёртых болванов как вы.

Ай-яй, вы уже меня оскорбляете, больше ваш воспаленный маразум не родил аргументов?

Я лишь констатирую факт.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Они возвращают ссылку на объект. Удивлены?

Да, думал иван очевиднев под другим ником тут петросянит, а вона как.

Тип этого объекта после компиляции неизвестен. Снова удивлены? Поэтому если посмотреть на код после компиляции вы увидете, что возвращается Object.

У вас все еще каша в голове. Оно вернет то что внутри него будет, т.е String, null или ваш любимый Object 8)

Явное преобразование типов вниз происходит только если вы написали этот тип в круглых скобках. Генерики делают это неявно.

17: checkcast #5; //class java/lang/String

Фигасе, неявно, уважаемый вы так и не сказали ваш диагноз.

Посмотрите ещё раз что такое raw types и перестаньте нести чушь. У raw types никакой параметризации нет и быть не может.

таки интересно, а как в вашей палате тяжелобольных назовется тот факт что у getStrings у возвращаемого типа есть String, или солипсизм ваша религия?

Я лишь констатирую факт.

Вы почка что лишь феерично выставляете себя идитом 8) у вас получается, хвалю.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Они возвращают ссылку на объект. Удивлены?

Да, думал иван очевиднев под другим ником тут петросянит, а вона как.

Да, после ваших предыдущих заявлений приходится напоминать общеизвестные факты.

> Тип этого объекта после компиляции неизвестен. Снова удивлены? Поэтому если посмотреть на код после компиляции вы увидете, что возвращается Object.

У вас все еще каша в голове. Оно вернет то что внутри него будет, т.е String, null или ваш любимый Object 8)

Оно вернёт ссылку, тип которой Object. На какой объект эта ссылка указывает совершенно не важно.

12:   invokeinterface   #4,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;

> Явное преобразование типов вниз происходит только если вы написали этот тип в круглых скобках. Генерики делают это неявно.

> 17: checkcast #5; //class java/lang/String

Фигасе, неявно, уважаемый вы так и не сказали ваш диагноз.

Товарищь Выферр, вы не отличаете исходный код от байт кода. К следующему экзамену приходите подготовленным.

> Посмотрите ещё раз что такое raw types и перестаньте нести чушь. У raw types никакой параметризации нет и быть не может.

таки интересно, а как в вашей палате тяжелобольных назовется тот факт что у getStrings у возвращаемого типа есть String, или солипсизм ваша религия?

Это называется параметризация, которую вы по незнанию отключили. Меня забавляет с каким упорством вы продолжаете игнорировать сей факт.

> Я лишь констатирую факт.

Вы почка что лишь феерично выставляете себя идитом 8) у вас получается, хвалю.

Куда уж мне до вас. Вы редкий, исчезающий вид белок, с неповторимым строением головного мозга.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Да, после ваших предыдущих заявлений приходится напоминать общеизвестные факты.

Попробуйте изучить чтонить не общеизвестное 8)

Оно вернёт ссылку, тип которой Object. На какой объект эта ссылка указывает совершенно не важно.

Бугага, у вас в голове каша.

Товарищь Выферр, вы не отличаете исходный код от байт кода.

Уважаемый, вы форум от сортира не отличаете, прекращайте срать и изучайте терминологию.

Это называется параметризация, которую вы по незнанию отключили.

Уважаемый, вы когда отключаете свет то обнаруживаете что из горячего крана течет канализация? Судя по всему в вашей реальности это так или вы просто жидко обкакались и теперь доказываете свою жиденькую точечку зрения.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Да, после ваших предыдущих заявлений приходится напоминать общеизвестные факты.

Попробуйте изучить чтонить не общеизвестное 8)

Чего и вам желаю.

> Оно вернёт ссылку, тип которой Object. На какой объект эта ссылка указывает совершенно не важно.

Бугага, у вас в голове каша.

Всегда забавляли такие упёртые идиоты как вы. Вам же уже показали байт код:

12:   invokeinterface   #4,  2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;

> Товарищь Выферр, вы не отличаете исходный код от байт кода.

Уважаемый, вы форум от сортира не отличаете, прекращайте срать и изучайте терминологию.

Прекращайте баловаться веществами, это уже не смешно.

> Это называется параметризация, которую вы по незнанию отключили.

Уважаемый, вы когда отключаете свет то обнаруживаете что из горячего крана течет канализация? Судя по всему в вашей реальности это так или вы просто жидко обкакались и теперь доказываете свою жиденькую точечку зрения.

Это клиника. Так упорно не признавать факта, что raw types не поддерживают параметризацию может только больной на голову человек.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Всегда забавляли такие упёртые идиоты как вы.

Валерианочкой уже потчевались, забавненький вы наш?

Вам же уже показали байт код:

Уважаемый я вам показывал несколько строчек ниже 8) нечто от чего вы фалломорфируете.

Прекращайте баловаться веществами, это уже не смешно.
Это клиника

Я смотрю у вас кончились аргументы 8)

что raw types не поддерживают параметризацию

Вы опять сказали бред, уважаемый 8) Изучите что такое raw type (подсказка - парметризованный тип без указанных параметров) и может вместе со мной поржете над тем как разбрызгивая слюну вы метанируете о том как параметризованные типы не поддерживают параметризацию 8) Да, а потом посморите на возвращаемый тип метода getStrings параметризованный (да, уважаемый, он параметризован!) типом String. Может тогда вашу палату отключат от инета?

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Всегда забавляли такие упёртые идиоты как вы.

Валерианочкой уже потчевались, забавненький вы наш?

Похоже клоун решил выступить на бис.

> Вам же уже показали байт код:

Уважаемый я вам показывал несколько строчек ниже 8) нечто от чего вы фалломорфируете.

От перехода на междометия ваши потуги сказать что-то умное таковыми не становятся.

> Прекращайте баловаться веществами, это уже не смешно. >Это клиника

Я смотрю у вас кончились аргументы 8)

Какие аргументы вам нужны? Вы не в состоянии отличить байт код от исходного кода. При этом вы упорствуете в своём неумении. Такой недуг аргументами не лечится.

> что raw types не поддерживают параметризацию

Вы опять сказали бред, уважаемый 8) Изучите что такое raw type (подсказка - парметризованный тип без указанных параметров) и может вместе со мной поржете над тем как разбрызгивая слюну вы метанируете о том как параметризованные типы не поддерживают параметризацию 8)

raw types не являются параметрезированными типами ни в коем разе. Вас кто-то обманул.

Да, а потом посморите на возвращаемый тип метода getStrings параметризованный (да, уважаемый, он параметризован!) типом String. Может тогда вашу палату отключат от инета?

А вы сами посмотрите. Откройте код ниже в IDE, подведите мышь к cont0.getStrings(); и затем к cont1.getStrings(); и удивитесь тому, что возвращаемые типы разные: List<String> и List соответственно.

import java.util.Arrays;
import java.util.List;

public class TestClass {

	public static void main(String[] args) {
		Container<?> cont0 = new Container();
		Container cont1 = new Container();
		Object obj0 = cont0.getStrings();
		Object obj1 = cont1.getStrings();
	}
}

class Container<T> {
	public List<String> getStrings() {
		return Arrays.asList("1", "2", "str");
	}
}

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Похоже клоун решил выступить на бис.

Хороший у вас эпиграф к вашему потоку бреда 8)

Вы не в состоянии отличить байт код от исходного кода.

Солипсизм вас не спасет 8)

raw types не являются параметрезированными типами ни в коем разе. Вас кто-то обманул.

Я вам нетривиально намекнул прочитать что нить кроме двача и посмотреть таки определение, а не метанировать.

А вы сами посмотрите. Откройте код ниже в IDE, подведите мышь к cont0.getStrings(); и затем к cont1.getStrings(); и удивитесь тому, что возвращаемые типы разные: List<String> и List соответственно.

Вот и выросло поколение идиотов кое делает две глупости:

1) не умеет думать без IDE

2) считает баг - закономерностью, ибо своего мозга нет.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> Похоже клоун решил выступить на бис.

Хороший у вас эпиграф к вашему потоку бреда 8)

Дислексия вас погубит.

> Вы не в состоянии отличить байт код от исходного кода.

Солипсизм вас не спасет 8)

А вас?

> raw types не являются параметрезированными типами ни в коем разе. Вас кто-то обманул.

Я вам нетривиально намекнул прочитать что нить кроме двача и посмотреть таки определение, а не метанировать.

Покажите же наконец определение raw types.

> А вы сами посмотрите. Откройте код ниже в IDE, подведите мышь к cont0.getStrings(); и затем к cont1.getStrings(); и удивитесь тому, что возвращаемые типы разные: List<String> и List соответственно.

Вот и выросло поколение идиотов кое делает две глупости: 1) не умеет думать без IDE; 2) считает баг - закономерностью, ибо своего мозга нет.

IDE предлагалось использовать в качестве демонстрации. Вы ещё скажите, что баг в компиляторе. Попробуйте откомпилировать следующий код:

import java.util.Arrays;
import java.util.List;

public class TestClass {

	public static void main(String[] args) {
		Container<?> cont0 = new Container();
		Container cont1 = new Container();
		String s0 = cont0.getStrings().get(0);
		String s1 = cont1.getStrings().get(0);
	}
}

class Container<T> {
	public List<String> getStrings() {
		return Arrays.asList("1", "2", "str");
	}
}

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Дислексия вас погубит.

Личный опыт?

А вас?

Вы о себе милейший беспокойтесь, диагноз то скрываете.

Покажите же наконец определение raw types.

Вы даже по собственным ссылкам не ходите? Бугага.

IDE предлагалось использовать в качестве демонстрации. Вы ещё скажите, что баг в компиляторе. Попробуйте откомпилировать следующий код:

Уважаемы, кажется вы начинаете подходить к истинной проблеме высказанной в начале топика. Главное не сбейтесь 8)

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> > Дислексия вас погубит.

Личный опыт?


Нет, наблюдения за страдающими этим недугом.

> А вас?


Вы о себе милейший беспокойтесь, диагноз то скрываете.


О себе я и без вас побеспокоюсь.

> Покажите же наконец определение raw types.


Вы даже по собственным ссылкам не ходите? Бугага.


Разумеется хожу. А вы там были? Сумели понять смысл текста?

> IDE предлагалось использовать в качестве демонстрации. Вы ещё скажите, что баг в компиляторе. Попробуйте откомпилировать следующий код:


Уважаемы, кажется вы начинаете подходить к истинной проблеме высказанной в начале топика. Главное не сбейтесь 8)


На ваш первоначальный вопрос (почему так сделано) уже был дан подробный ответ.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Нет, наблюдения за страдающими этим недугом.

Шизофреник значит.

О себе я и без вас побеспокоюсь.

Заметно 8)

Разумеется хожу. А вы там были? Сумели понять смысл текста?

Уважаемый, вас несет, вы определение привели?

На ваш первоначальный вопрос (почему так сделано) уже был дан подробный ответ.

Пока что вы тут лишь тщательно пропердывате каждую вашу ошибку 8)

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

Видимо по мнению разработчиков java объявление переменной как GenericClass gc = new GenericClass(); (вместо GenericClass<?> gc = ..) говорит о том, что вы не знакомы с generic и код не расчитан на их использование, поэтому он воспринимает возвращаемое значение не List<String>, а List<Object> как было бы с TypeErasure да нелогично и тупо.

Несмотря на логику т.к. myClass mc = new myClass(); объявлена без указания типа, то это считается rawType и в нём удаляется вся информация о generic типах, в итоге видим, что видим.

Но вдруг Вас чёрт дернет собрать проект в jdk-1.4 =)

ЗЫ а байткод не отличается. хотя в целом сложно привести идентичную программу с и без использования rawTypes

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Видимо по мнению разработчиков java объявление переменной как GenericClass gc = new GenericClass(); (вместо GenericClass<?> gc = ..) говорит о том, что вы не знакомы с generic и код не расчитан на их использование, поэтому он воспринимает возвращаемое значение не List<String>, а List<Object> как было бы с TypeErasure да нелогично и тупо.

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

и в нём удаляется вся информация о generic типах,

В том то и косяк что «вся» не должна, ни по логике ни даже по спецификации, ибо объявления типов никак не перескаются.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

Походу инопланетянская логика такая:

В for in: переменная типа String у нас не genericType => смотим на cont0 — он не rawType => не имеем права рассматривать возвращаемое значение как List<String>, а только как List<Object>

В примере по ссылке: ls параметризован типом String => это genericType => можем рассматрицать возвращаемый результат как List<String>

P.S. если что не так написал поправляйте.

P.P.S. В общем надо будет на свежую голову сделать пару-тройку тестов проверить, это предположение да и почитать ещё инфу.

qnikst ★★★★★
()
Ответ на: комментарий от wfrr

Скорее разработчики что-то там курили, ибо как показали примеры выше, внезапно все может начать работать.

 List<String> ls = cont0.getStrings(); 
  for(String s : ls){

Совсем не внезапно. Переменная ls объявлена как List<String>. А вот какой именно List возвращает cont0.getStrings() зависит от того, как объявлена cont0.

bbk123 ★★★★★
()
Ответ на: комментарий от qnikst

> Видимо по мнению разработчиков java объявление переменной как GenericClass gc = new GenericClass(); (вместо GenericClass<?> gc = ..) говорит о том, что вы не знакомы с generic и код не расчитан на их использование, поэтому он воспринимает возвращаемое значение не List<String>, а List<Object> как было бы с TypeErasure да нелогично и тупо.

Только не List<Object>, а просто List. Объявление GenericClass gc означает, в числе прочего, что gc не гарантирует безопасность неявного приведения типов. Поэтому такое приведение отключается и вы получаете просто List.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Совсем не внезапно.

Ваша амозглие никого не удивляет, совем не внезапно.

А вот какой именно List возвращает cont0.getStrings() зависит от того, как объявлена cont0.

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

wfrr ★★☆
() автор топика
Ответ на: комментарий от qnikst

он не rawType => не имеем права рассматривать возвращаемое значение как List<String>, а только как List

Пофиксил, щас догадаетесь почему

В примере по ссылке: ls параметризован типом String => это genericType => можем рассматрицать возвращаемый результат как List<String>

А вот тут нет, ради пресловутой совместимости компилятор жабы позволяет «приводить» raw type к любому другому типу, это вызовет лишь варнинг. Именно raw type, попробуйте привести List<Object> к List<String> и получите ошибку компиляции. Хотя, блин байткод ничем не отличается!

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> > А вот какой именно List возвращает cont0.getStrings() зависит от того, как объявлена cont0.

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


Расскажите, как вы собираетесь пользоваться параметризацией в режиме совместимости с Java 1.4.2?

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Процитированный вами мой текст имеет прямое отношение (в качестве аналогии) к способам включения режимов совместимости, точнее к его логичности и документированности 8)

wfrr ★★☆
() автор топика
Ответ на: комментарий от bbk123

Переменная ls объявлена как List<String>. А вот какой именно List возвращает cont0.getStrings() зависит от того, как объявлена cont0.

похоже, что всё не совсем так.

поскольку в следующем коде:

    public static void main(String[] args) { 
        Container cont0 = new Container(); //<-- raw Type
        List<String> ls = cont0.getStrings();// поидее должен возвращать List и нужно явное приведение типа.
        for(String s : ls){ 
            System.out.println(s); 
        } 
    } 

но код успешно компилируется, правда с выдавая warning.

Note: Main1.java uses unchecked or unsafe operations.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

List<String> ls = cont0.getStrings();// поидее должен возвращать List и нужно явное приведение типа.

Явного приведения List к List<String> не требуется. А вот в случае List<Object> --> List<String> оно невозможно ни «тайно», ни явно:

		List listRaw = new ArrayList();
		List<String> listGen;
		List<Object> listGen2 = new ArrayList<Object>();
		
		listGen = listRaw;	// компилируется
		listGen = listGen2;	// не компилируется
		listGen = (List<String>) listGen2; // не компилируется

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

> Явного приведения List к List<String> не требуется.

Неочевидное утверждение =)

ну пусть так.. тогда почему не работал код из первого поста, а именно (String s: cont0.getStrings()), ведь приведение List->List<String> не требуется, так, что компилятор вполне мог бы воспринимать код как List<String> ls = cont0.getStrings(); for (String s: ls) {. Что вполне возможно т.к. байткод 1 и 2 варианта _совершенно_ одинаковый. Ну может конечно, это средство обучения человеков generic'ам.

вопрос-то в этом был.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Ты ставишь ббк в неудобное положение, но он извернется 8), я в него верю 8)

wfrr ★★☆
() автор топика
Ответ на: комментарий от bbk123

С кем Вы спорите, уважайте свое время.

2wfrr ты достал своей чушью портить каждый тред о джаве. Если у тебя кривые руки и ты не осилил спеку, иди и читай. Достал уже своей непрошибаемой тупостью, коверканием языка и бараньей упертостью.

JFreeM ★★★☆
()
Ответ на: комментарий от qnikst

> Явного приведения List к List<String> не требуется.

Неочевидное утверждение =)

Почему неочевидное? Вы же видели код.

ну пусть так.. тогда почему не работал код из первого поста, а именно (String s: cont0.getStrings()), ведь приведение List->List<String> не требуется, так, что компилятор вполне мог бы воспринимать код как List<String> ls = cont0.getStrings(); for (String s: ls) {. Что вполне возможно т.к. байткод 1 и 2 варианта _совершенно_ одинаковый. Ну может конечно, это средство обучения человеков generic'ам.

for (String s: cont0.getStrings()) {...} это просто более краткая запись for (Iterator iter = cont0.iterator(); iter.hasNext();) {String s = iter.next(); ...}

Здесь нигде нет присваивания ссылки на List переменной, тип которой List<String>. Переменная iter может быть параметризированной, тоесть объявляться не как Iterator, а например как Iterator<String>. Для этого cont0.getStrings() тоже должен возвращать параметризированную ссылку. Но cont0.getStrings() возвращает List.

вопрос-то в этом был.

Изначально вопрос был в том, в чём логика такого поведения. Выферру объяснили, что raw types служат для совместимости со старым кодом и поэтому полностью отключают параметризацию для конкретной переменной. Старый код не гарантрует безопасность приведения типов. Старый код может вернуть ссылку на такой Container, getStrings() которого будет возвращать List содержащий не только String-и. Поэтому оставлять параметризацию для таких случаев просто глупо. При этом оставлена лазейка в виде возможности приводить непараметризированный тип к параметризированному. Например List к List<String>. При использовании этой лазейки компилятор вас обязательно предупредит, что вы делаете это на свой страх и риск.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

Вмемто cont0.iterator(); я хотел написать cont0.getStrings()iterator();

P.S. когда же maxcom позволит редактировать сообщения?

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

> Почему неочевидное? Вы же видели код.

Тут не код, тут документацию видеть надо. ;) хотя согласен, что тут тоже можно понять причину /совместимость со старыми версиями/.

for (String s: cont0.getStrings()) {...} это просто более краткая запись for (Iterator iter = cont0.iterator(); iter.hasNext();) {String s = iter.next(); ...}

ok, теперь ясно.

Хотя не совсем очевидно, что для данного метода нельзя использовать запись Iterator<String> iter = ...; т.к. байткод эквивалентен. Хотя в общем-то пофиг, если писать грамотно, то проблем нет.

Старый код может вернуть ссылку на такой Container, getStrings() которого будет возвращать List содержащий не только String-и. Поэтому оставлять параметризацию для таких случаев просто глупо.

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

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

> > Почему неочевидное? Вы же видели код.

Тут не код, тут документацию видеть надо. ;) хотя согласен, что тут тоже можно понять причину /совместимость со старыми версиями/.


http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#190772

> for (String s: cont0.getStrings()) {...} это просто более краткая запись for (Iterator iter = cont0.getStrings().iterator(); iter.hasNext();) {String s = iter.next(); ...}


ok, теперь ясно. Хотя не совсем очевидно, что для данного метода нельзя использовать запись Iterator<String> iter = ...; т.к. байткод эквивалентен. Хотя в общем-то пофиг, если писать грамотно, то проблем нет.


Можно. Достаточно объявить cont0 параметризированой переменной или сделать класс Container непараметризированным. Иначе оба варианта for компилироваться не будут.

> Старый код может вернуть ссылку на такой Container, getStrings() которого будет возвращать List содержащий не только String-и. Поэтому оставлять параметризацию для таких случаев просто глупо.


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


В любом случае, на уровне байткода, и List#get(int) и List<String>#get(int) возвращают Object. На уровне байткода это совершенно одинаковые методы и возвращать разные вещи они не могут принципиально. Кастинг делаете либо вы сами (как в Java 1.4.2), либо генерики за вас, но в любом случае после вызова метода.

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

> Можно. Достаточно объявить cont0 параметризированой переменной или сделать класс Container непараметризированным. Иначе оба варианта for компилироваться не будут.

наша песня хороша, начинай сначала :) поскольку тебе лень понимать про что именно тут пишется, а мне лень объяснять, что я хочу сказать, то чтобы не уходить в бессмысленную рекурсию, думаю стоит закрыть данную тему.

Как написать, чтобы это работало, я знаю ;)

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Неужели ты не понимаешь, что непераметризированный List не может вернуть параметризированный Iterator? В каком месте у тебя логическое несоответствие?

bbk123 ★★★★★
()
Ответ на: комментарий от bbk123

блин лень jdk-1.4.2 размаскировывать, чтобы проверить наверняка.

В общем вопрос в следующем

import java.util.Arrays; 
import java.util.List; 
import java.util.Iterator; 

public class Main { 
     
    public static void main(String[] args) { 
        Container<?> cont0 = new Container(); //generic Type
        Container    cont1 = new Container(); //raw Type
        Object ob = cont0.getStrings();
        
        // generic Type -> raw Iterator
        // no warinigs
        for (Iterator iter = cont0.getStrings().iterator(); iter.hasNext();) {
            //String s = iter.next();  <-- не работает
            String s = (String) iter.next();
        }
/*
   22:	invokevirtual	#4; //Method Container.getStrings:()Ljava/util/List;
   25:	invokeinterface	#5,  1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
   30:	astore	4
   32:	aload	4
   34:	invokeinterface	#6,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   39:	ifeq	57
   42:	aload	4
   44:	invokeinterface	#7,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   49:	checkcast	#8; //class java/lang/String
   52:	astore	5
   54:	goto	32
*/

        // generic Type -> generic Iterator
        // no warnings
        for (Iterator<String> iter = cont0.getStrings().iterator(); iter.hasNext();) {
            String s = iter.next(); 
            //code here
        }
/*
   58:	invokevirtual	#4; //Method Container.getStrings:()Ljava/util/List;
   61:	invokeinterface	#5,  1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
   66:	astore	4
   68:	aload	4
   70:	invokeinterface	#6,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   75:	ifeq	93
   78:	aload	4
   80:	invokeinterface	#7,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   85:	checkcast	#8; //class java/lang/String
   88:	astore	5
   90:	goto	68
*/

        //raw Type -> raw Iterator 
        //no warning
        for (Iterator iter = cont1.getStrings().iterator(); iter.hasNext();) {
            //String s = iter.next();  <- don't work
            String s = (String)iter.next();
            //code here
        }
/*
   94:	invokevirtual	#4; //Method Container.getStrings:()Ljava/util/List;
   97:	invokeinterface	#5,  1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
   102:	astore	4
   104:	aload	4
   106:	invokeinterface	#6,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   111:	ifeq	129
   114:	aload	4
   116:	invokeinterface	#7,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   121:	checkcast	#8; //class java/lang/String
   124:	astore	5
   126:	goto	104
*/
        //raw Type -> generic Iterator 
        //warning
        for (Iterator<String> iter = cont1.getStrings().iterator(); iter.hasNext();) {
            String s = iter.next(); 
            //code here
        }
/*
   130:	invokevirtual	#4; //Method Container.getStrings:()Ljava/util/List;
   133:	invokeinterface	#5,  1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
   138:	astore	4
   140:	aload	4
   142:	invokeinterface	#6,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   147:	ifeq	165
   150:	aload	4
   152:	invokeinterface	#7,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   157:	checkcast	#8; //class java/lang/String
   160:	astore	5
   162:	goto	140
*/        
    } 
} 
 
class Container<T> { 
    public List<String> getStrings() { 
        return Arrays.asList("1", "2", "str"); 
    }                    
}

как можно заметить генерирующийся байткод во всех случаях совершенно одинаковый и будет работать во всех версиях jre (чего и хотели добиться sun). Там, где не применимы generic (rawIterator) потребовался ручной кастинг.

Теперь вопрос о том, что подрузамевается под совместимостью с Java 1.4. Если то под какую версию java написаны исходные файлы и соотв как компилировать, то проект с generic не скомпилируется в принципе. Если имеется ввиду совместимость уже байткода, то как мы заметили разницы нет, и будут работать все написанные коды. и почему нельзя автоматизировать каст в 1м случае неясно (это примерно про это писал выфер). Вариант давайте ребята учитесь писать как надо, а старый варинат мы скоро отключим, не рассматривается, т.к. на мой взгляд он единственный логичный.

Если есть пример того, где данная идея работать не будет, или будет приводить к ошибкам, то хорошо бы его привести (если не сложно)

qnikst ★★★★★
()

Вот интересно, сколькими способами можно объяснять упорно и целенаправленно тупящей белке одно и то же? Причем результат, очевидно, по определению негативный - ибо белка НЕ ХОЧЕТ понять объяснения, а хочет ругать негодную жабку.

svu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.