Комментарии 52
Заголовок статьи и картинка вводят в заблуждение.
+7
Да, Java позволяет отстрелить себе ногу (это вы еще git не видели :))
С дженериками лучше, чем без них, удобнее: часть труда берет на себя компилятор. Конечно, его можно обмануть или ввести в заблуждение, только зачем?
Вообще, пост напоминает историю, как израильтяне хаммер перевернули.
С дженериками лучше, чем без них, удобнее: часть труда берет на себя компилятор. Конечно, его можно обмануть или ввести в заблуждение, только зачем?
Вообще, пост напоминает историю, как израильтяне хаммер перевернули.
+5
Почему не видел?=)
А я и не говорю, что с дженериками плохо. Мне просто совсем непонятно, почему нельзя было хранить ссылку на класс-параметр в объекте дженерика. В этом случае дженерики оставались бы дженериками и в рантайме.
А я и не говорю, что с дженериками плохо. Мне просто совсем непонятно, почему нельзя было хранить ссылку на класс-параметр в объекте дженерика. В этом случае дженерики оставались бы дженериками и в рантайме.
0
Обратная совместимость, не?
+1
Повторюсь, почему нельзя было сразу так сделать? Очевидное же решение. Подозреваю, что это связано со старыми коллекциями, но не владею точной информацией.
0
Вначале джененриков даже в мыслях не было. А потом пришлось делать костылями ради обратной совместимости.
+1
Я не разработчик языка. И потому судить о причинах и рассуждать «почему бы не хранить ссылку» — не могу. Авторам таки виднее, чем мне. Думаю, Выступления двух наших известных соотечественников, которые «пилят» производительность лямбды, показывают сколько «стекла» может крыться за с виду простым шагом. Поэтому… есть особенность, о ней надо знать. Можно свои идеи изложить в виде багрепорта. Можно просто смириться.
+1
На моей памяти эта обратная совместимость именно в энтерпрайз приложениях и чудила: проект с WebService, собранный JDK7, не запускается на JDK6. Что-то ему не ладно показалось в javax.ws.* Обратная совместимость — это не только формат классов. Это дохрена библиотек. Которые совершенствуются и включаются в JDK.
В общем, не верю я в сферическую совместимость в вакууме. Для какого-то конкретного приложения — может быть. Если авторы приложат руки и специально проверят.
В общем, не верю я в сферическую совместимость в вакууме. Для какого-то конкретного приложения — может быть. Если авторы приложат руки и специально проверят.
0
проект с WebService, собранный JDK7, не запускается на JDK6
Не наоборот?
0
Так ведь обратная совместимость языка, а не библиотек!
Смотрите, дженерики были введены в версии 1.5, до неё все делали все преобразования вручную. Проблема в том, что часть кода работала отличным от дженериков образом и внесение их в ВМ привело бы к краху многие приложения. А ведь до сих пор есть код, написанный под 1.4 (а крутится порой и на 1.7).
Смотрите, дженерики были введены в версии 1.5, до неё все делали все преобразования вручную. Проблема в том, что часть кода работала отличным от дженериков образом и внесение их в ВМ привело бы к краху многие приложения. А ведь до сих пор есть код, написанный под 1.4 (а крутится порой и на 1.7).
+1
В моем случае были не библиотеки а классы из состава самого JDK, в чем вся прелесть. Кроме того, после смены собственника старый софт часто намекает на левую java-машину и отказывается работать. OpenProj к примеру.
0
Ещё раз: совместимость языка. Классы JDK теоретически можно невозбранно заменять, как там с практикой — не знаю. Но даже в этом случае JDK стараются наращивать, а не менять (добавить nio, а не заменять io, добавить Collections, ...) Но есть случаи, когда меняют и JDK, обычно об этом заранее предупреждает свойство
@deprecated
0
Можно еще сделать простой импорт Y класса:
Выведет «life is good»
import ru.open.haven.client.gui.Test.X.Y;
public class Test {
public static class X {
public static class Y {
public static String Z = "life is good";
}
public static C Y;
}
public static class C {
public static String Z = "life is pain";
}
public static void main(final String[] args) {
System.out.println(Y.Z);
}
}
Выведет «life is good»
0
Дженерики в Java тот ещё выкидыш. И пока они обратную совместимость не поломают, ничего в лучшую сторону не изменится.
0
> Каст к типу дженерика — это костыль
Единственный ценный месседж: каст к типу дженерика пропадает в рантайме.
Кстати, это действительно так? Я не проверял, но что-то есть сомнения.
Забавно, но информация о дженериках полностью не стирается в рантайме.
См. docs.oracle.com/javase/6/docs/api/java/lang/reflect/Type.html и все что с ним связано, вроде:
docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#getGenericReturnType()
Единственный ценный месседж: каст к типу дженерика пропадает в рантайме.
Кстати, это действительно так? Я не проверял, но что-то есть сомнения.
Забавно, но информация о дженериках полностью не стирается в рантайме.
См. docs.oracle.com/javase/6/docs/api/java/lang/reflect/Type.html и все что с ним связано, вроде:
docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#getGenericReturnType()
+1
> Забавно, но информация о дженериках полностью не стирается в рантайме.
Да, её можно получить (к моей огромной радости в своё время): github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/inner/ReflectionUtils.java#L167
Да, её можно получить (к моей огромной радости в своё время): github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/inner/ReflectionUtils.java#L167
0
Или:
short a = 1;
short b = 2;
short z = a + b;
System.out.println(z);
Что выведет?
short a = 1;
short b = 2;
short z = a + b;
System.out.println(z);
Что выведет?
0
> Реализуйте метод, бросающий произвольный Throwable
Unsafe.getUnsafe().throwException(new IOException());
+1
Или так:
Thread.currentThread().stop(new IOException());
+1
Да, все верно, хоть и использовать deprecated методы и не комильфо;)
Все-таки подход к управлению потоками кардинально поменялся и это как раз тот случай, когда deprecated == нельзя, имхо.
Я не писал этот способ, потому что задание, все-таки, было «дополнительным» к дженерикам. Грубо говоря, на «усвоенный материал». На мой взгляд весьма забавное (как и каст нулла)
В любом случае, добавлю в пост, спасибо.
Все-таки подход к управлению потоками кардинально поменялся и это как раз тот случай, когда deprecated == нельзя, имхо.
Я не писал этот способ, потому что задание, все-таки, было «дополнительным» к дженерикам. Грубо говоря, на «усвоенный материал». На мой взгляд весьма забавное (как и каст нулла)
В любом случае, добавлю в пост, спасибо.
0
Ну, на то он и Unsafe. Так не интересно;) Просто так не напишете. В любом случае, добавлю, спасибо
0
НЛО прилетело и опубликовало эту надпись здесь
Нет
0
НЛО прилетело и опубликовало эту надпись здесь
Груви — это велосипед, от которого отказался автор языка. О чем тут еще можно говорить?
0
НЛО прилетело и опубликовало эту надпись здесь
Ну, этот отказался, другие подобрали. Что это доказывает? Как из этого можно ввести, что это плохой язык?
0
Автор) Я тебе подкину тоже веселый пример.
Могу сказать код скомпилится на все JDK, и не выполнится на любой(тестил 6-7-8, мб и где то пофиксили но я не видел)
public class GenericTest
{
public static void main(String[] args)
{
Map<Integer, Long> v = new HashMap<Integer, Long>();
v.put(1, 0L);
Long val = v.isEmpty() ? 0 : v.get(2);
System.out.println(val);
}
}
Могу сказать код скомпилится на все JDK, и не выполнится на любой(тестил 6-7-8, мб и где то пофиксили но я не видел)
0
Конечно, у вас вот тут:
Long val = v.isEmpty()? 0: v.get(2);
NPE, надо вот так:
Long val = v.isEmpty()? 0: v.get(1);
Long val = v.isEmpty()? 0: v.get(2);
NPE, надо вот так:
Long val = v.isEmpty()? 0: v.get(1);
0
Нет, v.get(2) возвращает null, который легко печатается System.out.println(). Если пример выше переписать через if:
То тоже будет работать. Как и другой код, что я уже написал. Так что вся хитрочть в операторе "?"
import java.util.*; public class GenericTest { public static void main(String[] args) { Map<Integer, Long> v = new HashMap<Integer, Long>(); v.put(1, 0L); if(v.isEmpty()) { System.out.println(0); } else { System.out.println(v.get(2)); } } }
То тоже будет работать. Как и другой код, что я уже написал. Так что вся хитрочть в операторе "?"
+1
Это особенность не дженерика, а оператора "?". В Java он не умеет выводить тип. Вот так работает:
import java.util.*; public class GenericTest { public static void main(String[] args) { Map<Integer, Long> v = new HashMap<Integer, Long>(); v.put(1, 0L); Long val = v.isEmpty() ? Long.valueOf(0) : v.get(2); System.out.println(val); } }
+3
Вопрос на засыпку — придумать пример из жизни, когда использование таких конструкций реально _необходимо_ ;-)
0
Мне кажется, в программировании отсутствует понятие «необходимости» как таковое. Всегда есть какое-то альтернативное решение. Всегда есть «архитектура лучше/выше/быстрее», «код понятнее/короче/круче». Потому-то оно и искусством считается=)
Но я понимаю вашу подколку. Не так давно у меня с коллегой был спор на тему полезности подобных извращенных задач. Мне кажется, я его убедил. Сделать это в тексте тяжелее, но я попробую.
Эти задачки — это не паттерны, это синтетические примеры, в которых неочевидное поведение языка (например) приводит к неожиданным результатам. И если встретить подобный пример в живом проекте вряд ли удастся (и слава богу) — понимание этой неочевидности краевых случаев _необходимо_ (противоречу сам себе с необходимостью;)).
Разумеется, так нельзя писать, но понимать, как устроены дженерики (что не нужно полагаться на тип и удивляться пришедшим багам), как разруливаются конфликты имен — никогда не повредит.
Но я понимаю вашу подколку. Не так давно у меня с коллегой был спор на тему полезности подобных извращенных задач. Мне кажется, я его убедил. Сделать это в тексте тяжелее, но я попробую.
Эти задачки — это не паттерны, это синтетические примеры, в которых неочевидное поведение языка (например) приводит к неожиданным результатам. И если встретить подобный пример в живом проекте вряд ли удастся (и слава богу) — понимание этой неочевидности краевых случаев _необходимо_ (противоречу сам себе с необходимостью;)).
Разумеется, так нельзя писать, но понимать, как устроены дженерики (что не нужно полагаться на тип и удивляться пришедшим багам), как разруливаются конфликты имен — никогда не повредит.
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
2 «простых» вопроса по джаве