Быстрый и грязный:
STRING=`echo 'dit /ZOU/ een test123' | perl -pe's/ //g;tr/[A-Z]/[a-z]/;s/[^a-zA-Z0-9]//g'`
При взаимодействии с устаревшим кодом, который не указывает параметры типа для универсальных типов, используйте подстановочный знак. Например, предположим, что вы вызываете метод в более старой библиотеке, который просто возвращает необработанную коллекцию
:
Collection getItems();
В своем коде назначьте результат переменной, объявленной с подстановочным знаком:
Collection<?> items = widget.getItems();
Таким образом, вы сохраняете безопасность типов, чтобы не получать никаких предупреждений.
Унаследованный код может указывать (скорее всего, в комментарии), какими должны быть общие параметры. Например:
/**
* @return the items, as a Collection of {@link Item} instances.
*/
Collection getItems();
В этом случае у вас есть выбор. Вы можете преобразовать результат в Collection
, но если вы это сделаете, вы на 100% полагаетесь на стороннюю библиотеку и отказываетесь от гарантии универсальных типов Java. : что любое ClassCastException
, возникшее во время выполнения, произойдет прямо при явном преобразовании.
Что делать, если вы не полностью доверяете сторонней библиотеке, но все же необходимо создать Collection
? Затем создайте новую коллекцию и добавьте содержимое после приведения его к ожидаемому типу. Таким образом, если в библиотеке есть ошибка, вы узнаете об этом сразу же, вместо того, чтобы иметь какой-то код далеко и гораздо позже таинственным образом взорвать исключение ClassCastException
.
Например:
Collection<?> tmp = widget.getItems();
Collection<Item> items = new ArrayList<Item>(tmp.size());
for (Object o : tmp)
items.add((Item) o); /* Any type error will be discovered here! */
Для случая, когда параметр типа неизвестен во время компиляции,
Вы можете просто составить список:
List raw = new ArrayList();
List<String> generic = (List<String>) raw;
Самый лучший и безопасный способ - это использовать метод java.util.Collections 'checkList(List list, Class type)'
С помощью этого метода все элементы в вашем старом Списке будут проверяться как можно раньше.
Если вы просто приведете к List
в любом старом месте, вы получите предупреждение компилятора "unchecked". Мы решили эту проблему, переместив ее в служебный метод.
public class Lists {
@SuppressWarnings({"unchecked"})
public static <T> List<T> cast(List<?> list) {
return (List<T>) list;
}
}
Вызывающая сторона теперь не получает предупреждения, например:
for (Element child : Lists.<Element>cast(parent.getChildren())) {
// ...
}
Эта утилита checkedList
в теории является отличной идеей, но на практике это отстой, когда приходится передавать класс, который вы ожидаете. Я надеюсь, что Java в конце концов получит информацию об общей типизации во время выполнения.