Получение ошибки Тип безопасности: снятый флажок от объекта до объекта ArrayList & lt; gt; .. при вызове jsp из сервлета [dубликат]

C ++ был разработан для добавления современных возможностей языка программирования в инфраструктуру C без лишнего изменения чего-либо о C, который не был конкретно о самом языке.

Да, на этом этапе (через 10 лет после первый стандарт C ++ и спустя 20 лет после того, как он начал серьезно расти в использовании), легко спросить, почему у него нет надлежащей модульной системы. Очевидно, что любой новый язык, который разрабатывается сегодня, не будет работать, как C ++. Но это не относится к C ++.

Точка C ++ должна быть эволюционной, гладкой продолжением существующей практики, только добавляя новые возможности без (слишком часто) нарушения вещей, которые адекватно работают для пользователя community

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

Вместо того, чтобы ожидать, что C ++ превратится в C # (что было бы бессмысленно, поскольку у нас уже есть C #), почему бы просто не выбрать подходящий инструмент для работы? Я сам пытаюсь написать важные фрагменты новой функциональности на современном языке (я использую C #), и у меня есть большое количество существующих C ++, которые я храню на C ++, потому что не было бы реальной ценности при повторной записи его все. В любом случае, они очень хорошо интегрируются, поэтому в значительной степени безболезненно.

198
задан FabienB 28 July 2011 в 19:34
поделиться

8 ответов

Ну, во-первых, вы теряете память с помощью нового HashMap вызова создания. Ваша вторая строка полностью игнорирует ссылку на этот созданный хэш, что делает ее доступной сборщику мусора. Итак, не делайте этого, используйте:

  private Map & lt; String, String & gt;  someMap = (HashMap & lt; String, String & gt;) getApplicationContext (). getBean ("someMap");   

Во-вторых, компилятор жалуется, что вы передали объект в HashMap , не проверяя, является ли это HashMap . Но даже если вы должны были сделать:

  if (getApplicationContext (). GetBean ("someMap") instanceof HashMap) {private Map & lt; String, String & gt;  someMap = (HashMap & lt; String, String & gt;) getApplicationContext (). getBean ("someMap");  }  

Возможно, вы все равно получите это предупреждение. Проблема в том, что getBean возвращает Object , поэтому неизвестно, что это за тип. Преобразование его в HashMap напрямую не вызовет проблемы со вторым случаем (и, возможно, в первом случае не было бы предупреждения, я не уверен, как педантичный компилятор Java с предупреждениями для Java 5). Тем не менее, вы преобразовываете его в HashMap & lt; String, String & gt; .

HashMaps - это действительно карты, которые берут объект в качестве ключа и имеют объект как значение, HashMap & lt; Object, Object & gt; , если хотите. Таким образом, нет никакой гарантии, что когда вы получите свой bean-компонент, он может быть представлен как HashMap & lt; String, String & gt; , потому что вы могли бы иметь HashMap & lt; Date, Calendar & gt; , потому что возвращаемое не общее представление может иметь любые объекты.

Если код компилируется, и вы можете выполнить String value = map.get («thisString»); без каких-либо ошибки, не беспокойтесь об этом предупреждении. Но если карта не полностью содержит строковые ключи для строковых значений, во время выполнения вы получите ClassCastException , потому что генерики не могут заблокировать это в этом случае.

219
ответ дан chelmertz 15 August 2018 в 23:00
поделиться
  • 1
    Это было давно, но я искал ответ на проверку типа Set & lt; CustomClass & gt; перед броском, и вы не можете использовать экземпляр на параметризованном родовом значении. например if (event.getTarget instanceof Set & lt; CustomClass & gt;) Вы можете ввести только тип проверки с помощью? и это не приведет к удалению предупреждения о броске. например if (event.getTarget instanceof Set & lt;? & gt;) – garlicman 14 February 2012 в 17:56

Как видно из вышеприведенных сообщений, список не может быть дифференцирован между List & lt; Object & gt; и List & lt; String & gt; или List & lt; Integer & gt; .

Я решил это сообщение об ошибке для аналогичной проблемы:

  List & lt; String & gt;  strList = (List & lt; String & gt;) someFunction ();  Строка s = strList.get (0);   

со следующим:

  List & lt;? & gt;  strList = (List & lt;? & gt;) someFunction ();  String s = (String) strList.get (0);   

Объяснение: Преобразование первого типа проверяет, что объект является списком, не заботясь о типах, находящихся внутри (поскольку мы не можем проверить внутренние типы на уровне списка). Второе преобразование теперь требуется, потому что компилятор знает, что List содержит какие-то объекты. Это проверяет тип каждого объекта в Списке по мере его доступа.

59
ответ дан Amarghosh 15 August 2018 в 23:00
поделиться
  • 1
    ты прав, мой друг. Вместо того, чтобы лить список, просто повторите его и отбросьте каждый элемент, предупреждение не появится, удивительно. – juan Isaza 5 October 2015 в 03:29
  • 2
    Это устранило предупреждение, но все же я не уверен: P – mumair 3 January 2017 в 11:52

Ниже кода причины Тип безопасности Предупреждение

Карта & lt; String, Object & gt; myInput = (Map & lt; String, Object & gt;) myRequest.get ();

Обходной путь

Создайте новый объект карты без упоминания параметры, потому что тип объекта, хранящийся в списке, не проверен.

Шаг 1: Создайте новую временную карту

Карта & lt; ? & GT; tempMap = (Map & lt;?,? & gt;) myRequest.get ();

Шаг 2: Создает главную карту

  Карта & lt; String, Object & gt;  myInput = new HashMap & lt; gt; (myInputObj.size ());   

Шаг 3: Итерируйте временную карту и установите значения в основную карту

  для (Map.Entry & lt ;?  ,? & gt; entry: myInputObj.entrySet ()) {myInput.put ((String) entry.getKey (), entry.getValue ());  }  
0
ответ дан Andy 15 August 2018 в 23:00
поделиться

Предупреждение. Предупреждение. Иногда предупреждения не имеют значения, иногда это не так. Они используются, чтобы привлечь ваше внимание к чему-то, что, по мнению компилятора, может быть проблемой, но может и не быть.

В случае бросков он всегда будет давать предупреждение в этом случае. Если вы абсолютно уверены, что конкретный бросок будет в безопасности, вам следует рассмотреть возможность добавления аннотации, подобной этой (я не уверен в синтаксисе) непосредственно перед строкой:

  @SuppressWarnings (  value = "unchecked")  
22
ответ дан David M. Karr 15 August 2018 в 23:00
поделиться
  • 1
    -1: предупреждение никогда не должно приниматься. Или подавите эти предупреждения или исправьте это. Наступит момент, когда вы будете иметь много предупреждений, и вы не увидите соответствующий один раз. – ezdazuzena 16 October 2013 в 10:58
  • 2
    Вы не можете действительно избегать предупреждений о бросании классов при кастинге параметризованных дженериков i.e Map, так что это лучший ответ на исходный вопрос. – muttonUp 8 March 2015 в 12:10

Вы получаете это сообщение, потому что getBean возвращает ссылку Object, и вы переводите ее в правильный тип. Java 1.5 дает вам предупреждение. Это характер использования Java 1.5 или лучше с кодом, который работает так. Spring имеет видную версию

  someMap = getApplicationContext (). GetBean & lt; HashMap & lt; String, String & gt; & gt; & gt; gt; («someMap»);   

в списке задач.

9
ответ дан David Nehme 15 August 2018 в 23:00
поделиться

Еще одно решение, если вы обнаружите, что вы очень сильно набрасываете один и тот же объект, и вы не хотите, чтобы ваш код был помечен с помощью @SupressWarnings («unchecked») , было бы создать метод с аннотаций. Таким образом, вы централизируете литье и, надеюсь, уменьшаете вероятность ошибки.

  @SuppressWarnings («unchecked») public static List & lt; String & gt;  getFooStrings (Map & lt; String, List & lt; String & gt; ctx) {return (List & lt; String & gt;) ctx.get ("foos");  }  
1
ответ дан Jeremy 15 August 2018 в 23:00
поделиться

Проблема заключается в том, что бросок - это проверка времени выполнения, но из-за стирания типа во время выполнения нет никакой разницы между HashMap & lt; String, String & gt; и HashMap & lt; Foo, Bar & gt; для любых других Foo и Bar .

Используйте @SuppressWarnings («unchecked») и удерживайте твой нос. О, и кампания для реинфицированных дженериков в Java:)

264
ответ дан Jon Skeet 15 August 2018 в 23:00
поделиться
  • 1
    Я возьму Java-редифики для нетипизированного NSMutableWhatever, который ощущается как десятилетний прыжок назад в любой день недели. По крайней мере, Java пытается. – Dan Rosenstark 3 August 2011 в 21:21
  • 2
    В точку. Если вы настаиваете на проверке типа, это может быть сделано только с помощью HashMap & lt;?,? & Gt; и это не приведет к удалению предупреждения, поскольку оно не совпадает с типом проверки общих типов. Это не конец света, но раздражает, что вы пойманы или подавляете предупреждение или живете с ним. – garlicman 14 February 2012 в 18:00
  • 3
    @JonSkeet Что такое reify generic? – SasQ 25 April 2016 в 06:27
  • 4

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

Например, если вы пытаетесь использовать

  private Map & lt; String, String & gt;  someMap = new HashMap & lt; String, String & gt; ();   

Вы можете создать новый класс, такой как

  public class StringMap extends HashMap & lt; String, String & gt; () {// Переписывать конструкторы}  

Тогда, когда вы используете

  someMap = (StringMap) getApplicationContext (). getBean ("someMap");   

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

5
ответ дан Rabbit 15 August 2018 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: