Помогите с ошибкой

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 03 янв 2014, 15:21

m090050 писал(а):
допускается неявное приведение типов — в случае, если значение одного типа присваивается переменной другого, то компилятор автоматически генерирует код для преобразования значения в нужный тип, если только такое преобразование не приводит к потере данных
Вы только что сами ответили на вопрос. Во-первых потеря данных на лицо (View не Button), во-вторых, строгая типизация (View не Button). И я не пойму, как это невозможно понять.
Button наследует TextView, который в свою очередь наследует View, наследуемый от object. Вы говорите о потере данных при обратном преобразовании - это понятно, но...

Пример:
View{ a, b, c };
Button extends view{ Override a };,
остальные переменные избыточны - это не интерфейс с обязательным переопределением полей/методов. Т.е. в данном случае использование типа View -избыточно для объекта Button, потому компилятор выполняет преобразование.
Пример по моему не удачный, но думать и писать код лень сегодня. А вот обратно преобразовать без потери данных и правда нельзя.
Изображение

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Помогите с ошибкой

Сообщение Mikhail_dev » 03 янв 2014, 15:25

Так вот, Button к View легко. Обратное неверно, о чем я и пытался сказать и опровергнуть Вас
другое дело, что указание (Button) в данном случае излишне, система сама определит тип.

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 03 янв 2014, 15:25

m090050 писал(а):
допускается неявное приведение типов — в случае, если значение одного типа присваивается переменной другого, то компилятор автоматически генерирует код для преобразования значения в нужный тип, если только такое преобразование не приводит к потере данных
Вы только что сами ответили на вопрос. Во-первых потеря данных на лицо (View не Button), во-вторых, строгая типизация (View не Button). И я не пойму, как это невозможно понять.
1. Преобразование присваивания
2. Преобразование вызова метода
3. Преобразование приведения
4. Строковое преобразование
5. Арифметическое расширение
Все это по сути не всегда имеет значение в повседневной жизни, но открывает некоторые границы, да и наверно зависит от реализации компилятора. Опять же это преобразования контекстов, в свою очередь в каждом контексте разрешены различные преобразования:
1. Тождественное преобразование
2. Расширяющее примитивное преобразование
3. Сужающее примитивное преобразование
4. Расширяющее ссылочное преобразование
5. Сужающее ссылочное преобразование
6. Строковые преобразования
Покажите мне где в Java есть неявное расширяющее ссылочное преобразование, уж очень интересно. И было бы интересно узнать про строковое преобразование.
2. Строковое преобразование применяется только к операндам двуместной операции "+", когда один из аргументов - String. В этом случае, другой аргумент операции "+" преобразовывается в String и результатом операции "+" будет новая строка, которая является конкатенацией двух строк. Строковое преобразование подробнее определено в описании операции "+"(конкатенация строк)
1. расширяющее ссылочное преобразование допустимо использовать в контексте присваивания при выполнении Преобразование присваивания, т.е.:
Следующие преобразования называются расширяющими ссылочными преобразованиями:

Любой классовый тип S в любой классовый тип T, при условии, что S - подкласс T. (Важный специальный случай расширяющего преобразования в классовый тип Object любого другого классового типа.)
Любой классовый тип S в любой интерфейсный тип K, при условии, что S реализует K.
Преобразование null в любой классовый тип, интерфейсный тип или тип массив.
Любой интерфейсный тип J в любой интерфейсный тип K, при условии, что J - подинтерфейс K.
Любой интерфейсный тип в тип Object.
Любой тип массив в тип Object.
Любой тип массив в тип Cloneable.
Любой тип массив SC [] в любой тип массив TC [], при условии, что SC и TC - ссылочные типы и имеется расширяющее преобразование SC в TC.
Изображение

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 03 янв 2014, 15:41

m090050 писал(а):Так вот, Button к View легко. Обратное неверно, о чем я и пытался сказать и опровергнуть Вас
другое дело, что указание (Button) в данном случае излишне, система сама определит тип.
Честно я не помню уже почему так и лень разбираться, да и в ваших словах логика мне абсолютно понятна. Но..:

[syntax=java]
View ok = findViewById(R.id.buttonOk);
Log.d("LogTag", ok.getClass().toString());
[/syntax]
возвращает: class android.widget.Button, Можете попробовать. Я не в состоянии сейчас показать причину и описать реализацию, судя по вашим сообщениям при желании вы легко разберетесь. По сути - дело в Override, все методы View - которые не переопределены компилятором были отброшены и View стал Button*(поскольку именно этого типа объект хранящийся по адресу сохраненному в константе R.id.buttonOk) по определению на этапе компиляции, хотя я не уверен, что это объяснение не запутает еще больше, да и оно не совсем корректно.
Изображение

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Помогите с ошибкой

Сообщение Mikhail_dev » 03 янв 2014, 23:52

возвращает: class android.widget.Button, Можете попробовать.
Да не о том разговор то идет. Я понимаю что у нас через рефлексию можно понять откуда класс, но суди дела это не меняет.
Верно Button a = (Button) findViewById(R.id.someButton);
Неверно Button a = findViewById(R.id.someButton); (ошибка компиляции ждет тут, потому что нет неявного приведения типа в данном случае)
Неверно View a = findViewById(R.id.someButton); (потому что мы приведем к суперклассу и получим только то, что умеет суперкласс View (привет наследование)).
Я честно говоря уже запутался в Ваших словах, в ваших усложнённых трактовках. Я же стараюсь донести очень простую вещь, которая является основой Java. Написав
ArrayList someObject = new ArrayList();
Object a = someObject;
код будет правильным, но мы получим только Object со всеми вытекающими методами самого класса Object. Другого, не дано. И пусть нам рефлексия говорит о том, что это ArrayList, она будет использована только как Objcet. Чтобы получить ArrayList, необходимо явное преобразование.
Если я не прав в такой простейшей вещи, то создайте тему и укажите где я не прав, мне будет безумно интересно, а то тут как-то наспамили. А если прав и Вы о том же, то это хорошо =)

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 04 янв 2014, 00:57

m090050 писал(а):
возвращает: class android.widget.Button, Можете попробовать.
Да не о том разговор то идет. Я понимаю что у нас через рефлексию можно понять откуда класс, но суди дела это не меняет.
Как раз суть это и меняет,я понял, что вам не понравилось именно выражение приведение типа к Button, понятно, что в данном случае оно не выполняется. Имел я ввиду то, что все равно компилятор будет видеть тип, как Button и ошибок не будет(только то, что не это причина ошибки я имел ввиду). Естественно что никто не нарисует во время компиляции этой кнопке методы, которых не было во View
Изображение

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Помогите с ошибкой

Сообщение Mikhail_dev » 04 янв 2014, 01:10

А что меняет? Что строго определенная переменная типа View превратится в Button? Не превратится никогда из-за строгой типизации
Имел я ввиду то, что все равно компилятор будет видеть тип, как Button и ошибок не будет(только то, что не это причина ошибки я имел ввиду).
Так не причина для ошибки или что ошибки не будет??? Вы уж определитесь

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 04 янв 2014, 01:25

m090050 писал(а):А что меняет? Что строго определенная переменная типа View превратится в Button? Не превратится никогда из-за строгой типизации
Имел я ввиду то, что все равно компилятор будет видеть тип, как Button и ошибок не будет(только то, что не это причина ошибки я имел ввиду).
Так не причина для ошибки или что ошибки не будет??? Вы уж определитесь
Вы забываете, что наш флуд в теме следствие, а не причина моих тут разглагольствований. В контексте вопроса это не причина для ошибки и ошибки тут не будет, опять же в конкретном примере, где задавался вопрос. Опять же Button лишь класс реализованный в Android framework, и ошибка в данном случае будет вызванна не потому, что я не привел явно тип, а потому, что в данном случае в объекте View может быть не реализован метод спецефичный для класса фреймворка.
Повторю далеко не я один придерживаюсь точки зрения, что в java псевдо строгая типизация и данном случае выполняя проверку типа - обект View -является объектом Button, откуда браться ошибке то?

Более того используя вью класс, ошибки не небудет, а нет. Да и метод find view by Id работает отлично без присваивания его переменной типа Кнопка. Потому, как ничего полезного в button не реализованно.
Изображение

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 04 янв 2014, 02:00

m090050 писал(а): Неверно Button a = findViewById(R.id.someButton); (ошибка компиляции ждет тут, потому что нет неявного приведения типа в данном случае)
ArrayList someObject = new ArrayList();
Object a = someObject;
код будет правильным, но мы получим только Object со всеми вытекающими методами самого класса Object. Другого, не дано. И пусть нам рефлексия говорит о том, что это ArrayList, она будет использована только как Objcet. Чтобы получить ArrayList, необходимо явное преобразование.
Если я не прав в такой простейшей вещи, то создайте тему и укажите где я не прав, мне будет безумно интересно, а то тут как-то наспамили. А если прав и Вы о том же, то это хорошо =)
Она не будет только переменно типа Object, а будет еще их ссылкой на ArrayList поддерживающий те же методы но реализация, это ваша проблема. Так и Button без явного приведения лишь говорит о не соответствии типа объекта, ссылкой на который есть переменная. Но никакого отношения к типу объекта, который будет иметь этот элемент, оно не имеет и как вы правильно заметили именно рефлексия позволяет динамически менять ее тип. При чем заметьте, что создавая объект: View ok = findViewById(R.id.buttonOk); кнопка полноценно работает именно, как Button.(хотя возможно я чего -то, что ее сломает не делал.)

Да и кто мне мешает вообще забыть о том, что есть во фреймворке тип Button и делать это так:
[syntax=java]
findViewById(R.id.buttonOk).setOnClickListener(new View.OnClickListener() {
...
});
[/syntax]
Неверно View a = findViewById(R.id.someButton); (потому что мы приведем к суперклассу и получим только то, что умеет суперкласс View (привет наследование)).
Интересно, что конкретно я не смогу делать с этой кнопкой? Для меня в случаях моего использования - все верно на 101%, хотя я не исключаю, что просто не сталкивался, поскольку вообще практически не касаюсь view элементов.
Последний раз редактировалось altwin 04 янв 2014, 02:18, всего редактировалось 3 раза.
Изображение

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Помогите с ошибкой

Сообщение Mikhail_dev » 04 янв 2014, 02:12

Вы забываете, что наш флуд в теме следствие, а не причина моих тут разглагольствований. В контексте вопроса это не причина для ошибки и ошибки тут не будет
Я тут перечитал что я написал. И да, действительно я неправильно сказал, сказав что будет ошибка
Дело может не в этом, но поиск кнопки таким образом, которым Вы ищете приведет к ClassCastException, к гадалке не ходи.
Но вот то что
altwin писал(а):
m090050 писал(а):
View btn = findViewById(R.id.button1);
Может всё таки так?
[syntax=java5]Button btn = (Button) findViewById(R.id.button1);[/syntax]
это странно, но допустимо и ошибку компиляции не вызывает. Только не спрашивайте зачем человек мог такое написать, другое дело, что указание (Button) в данном случае излишне, система сама определит тип.
То, что система сама определит тип и автоматически приведет переменную к Button типу, которая определена как View, это что-то из серии фантастики.
Опять же Button лишь класс реализованный в Android framework, и ошибка в данном случае будет вызванна не потому, что я не привел явно тип, а потому, что в данном случае в объекте View может быть не реализован метод спецефичный для класса фреймворка.
Что значит "может быть не реализован"? А может и реализован? А что если унаследуюсь и не буду ничего реализовывать? Ошибка будет? По вашей логике она не должна быть, по моей должна.
Повторю далеко не я один придерживаюсь точки зрения, что в java псевдо строгая типизация и данном случае выполняя проверку типа - обект View -является объектом Button
Да ни откуда. Ошибки не будет, как я сказал в этом посте. не знаю как я написал что она будет. И также не будет неявного преобразования к Butoon (View не может неявно привестись к Button).
Она не будет только переменно типа Object, а будет еще их ссылкой на ArrayList поддерживающий те же методы но реализация, это ваша проблема. Так и Button без явного приведения лишь говорит о не соответствии типа объекта, ссылкой на которы есть переменная.
Т.е. написали мое тоже самое, почти теми же словами. Уже хорошо. То что она является ссылкой... Ну даже не знаю. Я не счел нужным указывать на это, ибо думал не стоит говорить о том, что объекты всегда работают по ссылке.
Еще раз повторюсь. Вы же пишете о том, что можно с суперкласса без явного преобразования прыгнуть к наследнику. Это неверно.
P.S. с телефона писать очень не удобно :(
Не пишите с телефона =)

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Помогите с ошибкой

Сообщение altwin » 04 янв 2014, 02:21

То, что система сама определит тип и автоматически приведет переменную к Button типу, которая определена как View, это что-то из серии фантастики.
согласен :) а это я писал? тут очевидно что нельзя так делать)))
Что значит "может быть не реализован"? А может и реализован? А что если унаследуюсь и не буду ничего реализовывать? Ошибка будет? По вашей логике она не должна быть, по моей должна
А кто мешает мне его реализовать? Ошибки не будет если не использовать то, что не реализовано - это моя логика.
Еще раз повторюсь. Вы же пишете о том, что можно с суперкласса без явного преобразования прыгнуть к наследнику. Это неверно.
помоему я просто пока не научился выражать своей мысли. поскольку даже для меня подобное звучит довольно странно...

Да я не отказываюсь и во многом с вами согласен, но повторю - View ok = findViewById(R.id.buttonOk); Работает корректно в приложении. Кнопка выполняет все функции, которые я на нее возложил, более того объект имеет тип Button. Естественно я вижу что мои слова были о том, что не нужно (Button), и вот тут я не совсем понял как я это написал...

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

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Помогите с ошибкой

Сообщение Mikhail_dev » 04 янв 2014, 09:55

View ok = findViewById(R.id.buttonOk);
А что ей не работать то? findViewById возвращает View. Я ошибочно написал то сообщение. Имел ввиду что View тут никогда не станет Button, потому как она View, хоть в душе и Button. В общем разговор об одном и том же. Хотя было забавно =))

Ответить