Интересные находки и наблюдения #1

Поиск метода си-подобного языка при помощи регулярных выражений

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

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

1
^(\s+)public static void temp\(DoubleVector<T> d\) \{[\w\W]+^\1\}

С помощью такого регекса можно легко отыскать такой метод:

1
2
3
4
5
public static void temp(DoubleVector d) {
if (d !=null){
d.add(5);
}
}

О флагах: такой регекс сработает только при включённом флаге Multiline для того, что бы знаки ^ означали не только начало текста, но и начало строки. Вместо привычного .+ приходится использовать некий велосипед [\w\W]+. Это обусловлено тем, что обычная точка не включает в себя специальные символы, такие как \n, а флаг DotAll конфликтует с флагом Multiline в некоторых реализациях (например, в Python).

Динамическое приведение типов и его использование в Java 8

По материалам Casting In Java 8 (And Beyond ?)

Есть привычный способ приведения типов, который постоянно используется:

1
2
3
4
Object obj;
if (obj instanceof Integer){
Integer objInt = (Integer) objl;
}

В этом случае сразу задаётся компилятору тип Integer. Поскольку компилятор ещё на этапе компиляции знает тип, к которому будет приводиться объект, такой способ приведения типов называется статический.

В Java 5 ввели ещё дополнительный способ приведения типов.

1
2
3
4
5
Object obj; // may be an integer
if (Integer.class.isInstance(obj)) {
Integer objAsInt = Integer.class.cast(obj);
// do something with 'objAsInt'
}

Или в случае дженериков:

1
2
3
4
5
6
Object obj; // may be an integer
Class <T> type = // may be Integer.class
if (type.isInstance(obj)) {
T objAsType = type.cast(obj);
// do something with 'objAsType'
}

Поскольку в данном случае компилятор не знает, к какому конкретно типу будет приводиться объект, этот способ приведения называется динамическим.

Использование в Java 8

Довольно часто в работе с Optional<T> и Stream<T> приходится прибегать к приведению типов. Использования динамического приведения типов может сделать ваш код проще.
Например, с использованием статического приведения типов

1
2
Optional<?> obj; // may contain an Integer
Optional<Integer> objAsInt = obj.filter(obj -> obj instanceof Integer).map(obj -> (Integer) obj);

С динамическим приведением типов:

1
2
Optional<?> obj; // may contain an Integer
Optional<Integer> objAsInt = obj.filter(Integer.class::isInstance).map(Integer.class::cast);