Статьи

Пожалуйста, Java.

Я понимаю идею, что Java-язык довольно сложно поддерживать обратно-совместимым способом. Я понимаю идею JDK API, такую ​​как коллекции, чтобы быть довольно жестким, чтобы не сломать. Да.

Я не понимаю, почему в Java до сих пор нет многострочных строковых литералов.

Как часто вы пишете код JDBC (или любой другой внешний язык или разметку, скажем, JSON или XML, который вы хотите встроить в Java), как это?

1
2
3
4
5
6
7
try (PreparedStatement s = connection.prepareStatement(
    "SELECT * "
  + "FROM my_table "
  + "WHERE a = b "
)) {
    ...
}

В чем проблема?

  • Синтаксическая корректность , т.е. не забудьте добавить пробел в конце каждой строки
  • Стиль в языке хоста против стиля во внешнем языке , конечно, приведенный выше код выглядит «красиво» отформатированным в Java, но он не отформатирован для потребляющей стороны сервера
  • Внедрение SQL , разве мы не учили наших младших специалистов не выполнять этот тип конкатенации строк в SQL, чтобы предотвратить внедрение SQL? Конечно, вышесказанное все еще безопасно, но что удерживает менее опытного сопровождающего от случайного встраивания пользовательского ввода?

Сегодня я работал с некоторым кодом, написанным на Xtend , очень интересном языке, который компилируется в исходный код Java. Xtend исключительно полезен для создания шаблонов (например, для создания API Record1Record22 jOOQ ). Я заметил еще одну очень приятную особенность многострочных строк:

Отсутствие необходимости убегать!

Многострочные строки в Xtend заканчиваются тройными апострофами. Например

1
2
// Xtend
val regex = '''import java\.lang\.AutoCloseable;'''

Да, приведенное выше является допустимым регулярным выражением Java. Я AutoCloseable точек при сопоставлении импорта типа AutoCloseable . Мне не нужно делать это утомительное двойное экранирование, которое я должен делать в обычных строках, чтобы сказать компилятору Java, что обратная косая черта действительно является обратной косой чертой, а не экранированием Java следующего символа:

1
2
// Java
String regex = "import java\\.lang\\.AutoCloseable;";

Итак … Переведенный в наш исходный пример SQL, я бы хотел написать так:

1
2
3
4
5
6
7
try (PreparedStatement s = connection.prepareStatement(
    '''SELECT *
       FROM my_table
       WHERE a = b'''
)) {
    ...
}

С большим приятным плюсом: интерполяция строк (даже в PHP)!

1
2
3
4
5
6
7
8
9
String tableName = "my_table";
int b = 1;
try (PreparedStatement s = connection.prepareStatement(
    '''SELECT *
       FROM ${tableName}
       WHERE a = ${b}'''
)) {
    ...
}

Небольшое, но очень эффективное улучшение

Это было бы очень маленьким (с точки зрения бюджета сложности языка: всего один новый токен), но очень эффективным улучшением для всех нас, кто встраивает внешний язык (SQL, XML, XPath, Regex, вы его называете) в Java , Мы делаем это много. И мы ненавидим это.

Он не должен быть таким мощным, как многострочные строковые литералы Xtend ( которые действительно потрясают своим управлением пробелами для форматирования и шаблонных выражений ). Но это было бы начало.

Пожалуйста, сделайте это новогодним разрешением! 🙂